文章目录
JMM
并发领域的关键问题
线程间通信
线程的通信是指线程之间以何种机制来交换信息。在编程中,线程之间的通信机制有两种,共享内存和消息传递。
- 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信,典型的共享内存通信方式就是通过共享对象进行通信。
- 在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信,在java中典型的消息传递方式就是wait()和notify()。
线程间同步
同步是指程序用于控制不同线程之间操作发生相对顺序的机制。
- 在共享内存并发模型里,同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。
- 在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。
Java内存模型-JMM(Java Memory Model)
JVM内存模型中包括:
- 程序计数器(PC)
- java虚拟机栈
- 本地方法栈
- java堆
- 方法区
在多线程环境下,线程之间的要通信,就不得不提JMM(java内存模型)
在JVM内部使用的java内存模型(JMM)将线程堆栈和堆之间的内存分开
- 在JVM内部,Java内存模型把内存分成了两部分:线程栈区和堆区
- JVM中运行的每个线程都拥有自己的线程栈,线程栈包含了当前线程执行的方法调用相关信息,我们也把它称作调用栈
- 堆区包含了Java应用创建的所有对象信息,不管对象是哪个线程创建的,其中的对象包括原始类型的封装类(如Byte、Integer、Long等等)。不管对象是属于一个成员变量还是方法中的局部变量,它都会被存储在堆区。
- 从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。
Java多线程的实现手段(详见其他关于并发操作博客)
volatile关键字
-
可见性。对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
-
原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。
volatile可以保证内存可见性,不能保证并发有序性
synchronized同步机制
一个线程执行互斥代码过程如下:
-
获得同步锁;
-
清空工作内存;
-
从主内存拷贝对象副本到工作内存;
-
执行代码(计算或者输出等);
-
刷新主内存数据;
-
释放同步锁。
synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。
参考自: