1.并发问题:可见性,原子性和有序性
cpu缓存会导致可见性,线程切换会导致原子性(count++不是原子的),编译优化会带来有序性问题(双重锁单例)
2.java如何解决可见性和有序性
禁用缓存和编译优化即可解决,但是会导致性能非常低,需要程序员告知jvm按需禁用。方法是volitale,synchronize,final三个关键字和6项happens-before原则
3.happens-before
前面操作的结果对后续操作可见,主要对编译器有如下6点约束
3.1程序顺序原则,一个线程中,按照程序顺序执行。比如:x=62;v=true。x=62的修改对v=true操作的时候可见
3.2 volitale变量原则,对一个volitale变量的写操作,后续的读操作都可见。
3.3 传递性,A happens-before B,B happens-before C,那么A happens-before C
如下例子A线程写,B线程读,最终结果X=42
image.png
3.4 管程中的锁
锁的解锁happens-before锁的加锁,管程是一种通用的同步原语,java中就是synchronize
3.5 线程start原则
A线程启动子线程B,子线程B可以看到A线程调用子线程B之前的操作
3.5 线程join原则
A线程调用B线程的join方法,B线程的执行动作对A线程可见
网友评论