并发编程模型是解决线程之间如果通信以及线程之间如果同步问题的解决方案。在命令式编程模式中,线程之间通信有两种方式:共享内从和消息传递。java内存模型采用的共享的内存模型。所以java线程之间的通信是隐式的,对于程序员来说是透明的。所以在编写多线程程序时要理解隐式进行的通信机制。
java中所有实例域,静态域和数组元素都是存在堆内存中,堆内存是线程共享的,方法参数和局部变量不在线程间共享不受内存模型的影响。JMM定义了这样一种机制:线程之间的共享变量存储咋主存中,每个线程有一个私有的本地内存,本地内存存储了该线程以读写变量的副本。示意图如下:
JMM示意图线程A和线程B通信步骤是:
1. 线程A吧本地内存中更新的共享变量刷新到主存中
2. 线程B从主存中读取被线程A已经更新的共享变量
但是在执行java程序是由于要提高性能,编译器和处理器常常要对程序指令进行重新排序,这样就可能导致B线程读到A更新之前的共享变量的值。
为了保证内存可见性,java从1.5开始使用happens-before原则来阐述内存的可见性
1. 一个线程中操作,happens-before于该线程中的任意后续操作
2. 对于一个监视器的解锁,happens-before于随后对这个监视器的加锁
3. 对弈一个volatile变量的写操作,happens-before于任意后续对于这个变量的读操作
4. 如果A happens-before于B,Bhappens-before于C,吧A一定 happens-before于C
注意happens-before原则并不意味之前一个操作要在后一个操作之前执行,而是指一个前操作对于后一个操作可见。
网友评论