Java高并发-Java内存模型和线程安全
一、原子性
原子性是指一个操作是不可中断的。即使在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰。
i++是原子操作吗?
不是,包含3个操作:读i,i=i+1,写i
32位的机子上读取64位的long型也不是原子操作
二、有序性
2.1 举例
在并发时,程序的执行可能会出现乱序
2.2 步骤
一条指令的执行是可以分为很多步骤的:
- 取指IF
- 译码和取寄存器操作数ID
- 执行或者有效地址计算EX
- 存储器访问MEM
- 写回WB
流水线执行指令
分析:
指令分解成不同阶段
假设一条指令消耗一个CPU时钟周期
5个人生产一个产品,5个人同时工作
a=b+c
读b
读c
计算b+c,结果放到a
写a
分析:
进行优化,使气泡尽可能的少
分析:
调整指令顺序,可以消除气泡
三、可见性
3.1 定义
可见性是批当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道这个修改。
- 编译器优化
- 硬件优化(如写吸收,批操作)
批量操作,把操作进行积累,只把最终结果写入
3.2 Java虚拟机层面的可见性
http://hushi55.github.io/2015/01/05/volatile-assembly
public class VisibilityTest extends Thread {
private boolean stop;
public void run() {
int i = 0;
while (!stop) {
i++;
}
System.out.println("finish loop,i=" + i);
}
public void stopIt() {
stop = true;
}
public boolean getStop() {
return stop;
}
public static void main(String[] args) throws Exception {
VisibilityTest v = new VisibilityTest();
v.start();
Thread.sleep(1000);
v.stopIt();
Thread.sleep(2000);
System.out.println("finish main");
System.out.println(v.getStop());
}
}
分析:
stop变量加volatile就不会有这个问题了
四、Happen-Before
五、线程安全的概念
指某个函数、函数库在多线程环境中被调用时,能够正确地处理各个线程的局部变量 ,使程序功能正确完成。
i++在多线程下访问的情况: