本文共 1588 字,大约阅读时间需要 5 分钟。
线程间操作有:
所有线程间操作,都存在可见性问题,JMM需要对其进行规范
可见性问题:让一个线程对共享变量的修改,能够及时的被其他线程看到。 Java内存模型规定:对volatile变量v的写入,与所有其他线程后续对v的读同步。
要满足这些条件,所以volatile关键字就有这些功能:
volatile变量的访问控制符会加个
ACC_VOLATILE
——https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5由于《Java语言规范》的原因,对非volatile的double、long的单次写操作是分两次来进行的,每次操作其中32位,这可能导致第一次写入后,读取的值是脏数据,第二次写完成后,才能读到正确值。
对volatile变量v的写入,与所有其他线程后续对v的读同步。
对于监视器m的解锁与所有后续操作对于m的加锁同步。
对于每个属性写入默认值(0,false,null)与每个线程对其进行的操作同步。
启动线程的操作与线程中的第一个操作同步。
线程T2的最后操作与线程T1 发现线程T2已经结束同步。(isAlive,join可以判断线程是否终结)
如果线程T1中断了T2,那么线程T1的中断操作与其他所有线程发现T2被中断了同步。通过抛出InterruptedException
异常,或者调用Thread.interrupted
或Thread.isInterrupted
happens-before 关系用于描述两个有冲突的动作之间的顺序,如果一个action happens before 另一个action,则第一个操作被第二个操作可见,JVM需要实现如下happens-before规则:
start()
方法 happens-before被启动线程中的任意动作。t2.join()
,则t2中的所有操作对t1可见。当程序中包含两个没有被 happens-before 关系排序的冲突访问时,就称存在数据竞争。遵守了这个原则,也就意味着有些代码不能进行重排序,有些数据不能缓存!
转载地址:http://emugn.baihongyu.com/