保证线程安全方法 :
1, 不要跨线程访问共享变量
2, 使共享变量是 final类型的
3, 将共享可变数据的操作加上同步
当多线程共享可变数据时,每个读或者写的线程都必须执行同步。
可变数据同步方法:
1. synchronized
2. volatile 共享原子数据,非原子操作也要同步
3. ReentrantLock锁
4. Atomic类
5. 并发集合CopyOnWriteList、ConcurrentHashMap、BlockingQueue
6. concurrent框架
7. executor框架
反面案例
/**
* Broken! requires synchronization!
*/
public class SerialNumUtils {
public static volatile int serialNum = 0;
public static int getNetSerialNum() {
return serialNum++;
}
}
正确示例1
/**
* volatile synchronized
*/
public class SerialNumUtils200 {
public static volatile int serialNum = 0;
public synchronized static int getNetSerialNum() {
return serialNum++;
}
}
正确示例2
import java.util.concurrent.atomic.AtomicLong;
/**
* atomic long
*/
public class SerialNumUtils300 {
public static AtomicLong serialNum = new AtomicLong();
public static long getNetSerialNum() {
return serialNum.getAndDecrement();
}
}
特殊示例
// Broken! - How long would you expect this program to run? - Page 259
//我的虚拟机上可以正常停止,但是有些虚拟机做过优化,则不一定能正确结束
import java.util.concurrent.*;
public class StopThread {
private static boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested) {
System.out.println(i);
i++;
}
/* 有些虚拟机优化成if(!stopRequest) while(true) i++; */
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
本文深入探讨了多线程环境下保证线程安全的关键策略,包括避免跨线程访问共享变量、使用final类型变量、同步可变数据操作等。通过对比实例,展示了正确与错误的实现方式,并提供了多种同步方法,如`synchronized`关键字、`volatile`关键字、`ReentrantLock`锁、`Atomic`类、并发集合以及`concurrent`框架的应用。最后,通过一个反面案例说明了不恰当同步可能导致的问题。

被折叠的 条评论
为什么被折叠?



