http://www.jasongj.com/java/thread_safe/
1.多线程编程中的三个核心概念 原子性 可见性 顺序性
2.Java如何解决多线程并发问题
Java如何保证原子性(锁/同步/CAS ) Java如何保证可见性(volatile) Java如何保证顺序性(锁/同步/volatile/jvm 通过happens-before原则)
happens-before原则(先行发生原则)
传递规则:如果操作1在操作2前面,而操作2在操作3前面,则操作1肯定会在操作3前发生。该规则说明了happens-before原则具有传递性
锁定规则:一个unlock操作肯定会在后面对同一个锁的lock操作前发生。这个很好理解,锁只有被释放了才会被再次获取 volatile变量规则:对一个被volatile修饰的写操作先发生于后面对该变量的读操作 程序次序规则:一个线程内,按照代码顺序执行 线程启动规则:Thread对象的start()方法先发生于此线程的其它动作 线程终结原则:线程的终止检测后发生于线程中其它的所有操作 线程中断规则: 对线程interrupt()方法的调用先发生于对该中断异常的获取 对象终结规则:一个对象构造先于它的finalize发生 volatile适用场景
volatile适用于不需要保证原子性,但却需要保证可见性的场景。一种典型的使用场景是用它修饰用于停止线程的状态标记。如下所示
boolean isRunning = false; public void start () { new Thread( () -> { while(isRunning) { someOperation(); } }).start(); } public void stop () { isRunning = false; } 在这种实现方式下,即使其它线程通过调用stop()方法将isRunning设置为false,循环也不一定会立即结束。可以通过volatile关键字,保证while循环及时得到isRunning最新的状态从而及时停止循环,结束线程。
3.线程安全十万个为什么
问:平时项目中使用锁和synchronized比较多,而很少使用volatile,难道就没有保证可见性? 答:锁和synchronized即可以保证原子性,也可以保证可见性。都是通过保证同一时间只有一个线程执行目标代码段来实现的。
问:锁和synchronized为何能保证可见性? 答:根据JDK 7的Java doc中对concurrent包的说明,一个线程的写结果保证对另外线程的读操作可见,只要该写操作可以由happen-before原则推断出在读操作之前发生。
The results of a write by one thread are guaranteed to be visible to a read by another thread only if the write operation happens-before the read operation. The synchronized and volatile constructs, as well as the Thread.start() and Thread.join() methods, can form happens-before relationships.
问:既然锁和synchronized即可保证原子性也可保证可见性,为何还需要volatile? 答:synchronized和锁需要通过操作系统来仲裁谁获得锁,开销比较高,而volatile开销小很多。因此在只需要保证可见性的条件下,使用volatile的性能要比使用锁和synchronized高得多。
问:既然锁和synchronized可以保证原子性,为什么还需要AtomicInteger这种的类来保证原子操作? 答:锁和synchronized需要通过操作系统来仲裁谁获得锁,开销比较高,而AtomicInteger是通过CPU级的CAS操作来保证原子性,开销比较小。所以使用AtomicInteger的目的还是为了提高性能。
问:还有没有别的办法保证线程安全 答:有。尽可能避免引起非线程安全的条件——共享变量。如果能从设计上避免共享变量的使用,即可避免非线程安全的发生,也就无须通过锁或者synchronized以及volatile解决原子性、可见性和顺序性的问题。
问:synchronized即可修饰非静态方式,也可修饰静态方法,还可修饰代码块,有何区别 答:synchronized修饰非静态同步方法时,锁住的是当前实例;synchronized修饰静态同步方法时,锁住的是该类的Class对象;synchronized修饰静态代码块时,锁住的是synchronized关键字后面括号内的对象。