导致Java多线程可见性问题的原因是因为缓存问题,而导致有序性问题的原因是编译优化,直观的解决问题就是禁用缓存和禁用编译优化(选择性)
具体方法:
volatile,synchronized 和 final 三个关键字,以及六项Happens-Before 规则
Happens-Before:
1.程序的顺序性规则
程序对前面变量的需求一定对后面可见
2.volatile规则
对一个volatile变量的写操作,对于后续的读操作可见。
3.传递性
操作a如果happen-before 操作b ,操作bhappen-before操作c,那么a hapen-before 操作c。
4.管程中锁的规则
synchronized,synchronized 是 java 对管程的实现。
5.线程 start() 规则
A 启动子线程 B 后,子线程 B 能够看到主线程在启动子线程b前的所有操作。
6.线程join()规则
线程a在等待线程b完成操作时,主线程的线程a对线程b的所有操作可见,既变量共享。
final
这个关键字告诉编译器,这个变量生而不变 可以使劲优化。