Java并发相关概念
![](https://img.haomeiwen.com/i7077265/62a99f965ac49d09.gif)
这是Java内存结构模型,其实还有更复杂的CPU高速缓存,这里略过,只讲working memory与main memory。
working memory,线程工作内存,线程私有,对应的操作:lock、load、use、assign、store、unlock
load:将main memory的值复制到working memory
use:在workingmemory中改变值
assign:对值进行其他操作,如从操作数栈弹出,赋给局部变量区
store:将变量值从working memory复制到main memory
main memory,主内存,线程共享,对应的操作:lock、read、write、unlock
关于volatile
volatile仅能保证修饰对象的可见性,不能保证在此对象上的操作的原子性。(jdk1.5之后还能够保证修饰的对象禁止指令重排)
volatile修饰的变量,线程不会将其从main memory复制到work memory,而是直接在main memory中操作。它的代价比synchronized、lock/unlock低,但用起来要非常小心,毕竟不能保证原子操作。
使用volatile的场景:对当前变量的改变不依赖于变量之前的值,如boolean标志位。
线程交互:
wait、notify、notifyAll
当线程调用了对象的wait方法后,JVM线程执行引擎会将次线程放入一个wait sets中,并释放该线程在对象上的锁。wait set中的线程不会被JVM线程执行引擎调度执行。
当其他线程调用了此对象的notify方法时,会从wait sets中随机找一个等待在此对象上的线程,并将其从wait sets中移除,这样JVM线程执行引擎就可以再次调度执行该线程了。
当调用的是notifyAll方法时,会删除wait sets上所有等待在此对象上的线程,然后释放锁,让它们竞争锁。
线程生命周期:
线程分为几种不同的状态,根据状态放入不同的sets来进行调度
刚创建时,为new状态
调用start方法后,进入runnable状态,放入JVM的可运行线程队列中,等待CPU执行权限
JVM按照线程优先级、时间片、轮循方式来执行runnable状态的线程
线程进入start代码段,开始执行,状态变为running
执行过程中出现了sleep、wait、join或者出现IO阻塞、锁等待时,则进入wait或blocked状态,这是线程放弃CPU时间片进入wait sets或锁sets
知道wait结束,线程被唤醒或获取到锁,线程在此进入runnable状态
线程执行完毕,线程就从可运行线程队列中删除了。