基本thread的同步方式
java
对于多thread中存在的数据竞争,须要利用java平台提供的同步机制来确保对共享变量的访问存在合适的“在以前发生”(happens-before)的顺序。java平台提供的基本同步方式包括synchronized关键词和object类中提供的wait,notify和notifyAll方法。
缓存
synchronized,能够添加到方法或代码块之上。声明为synchronized的方法或代码块在同一时刻只能有一个thread容许访问。若是当前已有thread正在访问,那么其余试图访问该方法或代码块的thread会处于等待状态。全部的java对象都有一个与之关联的监视器对象monitor。容许thread在该monitor对象上进行加锁和解锁操做。jvm在锁被释放时,对共享变量的修改会从cpu缓存中直接写回到主存中,当锁被获取时,cpu的缓存中的内容被置为无效状态,直接从主存中从新读取共享变量的值。
app
正确的使用synchronized是把方法中须要同步的代码用synchronized代码块包围便可。
jvm
Object类的wait,notify,notifyAll方法
性能
synchronized关键字主要用来实现thread间互斥,即同一时刻只有一个thread容许执行特定代码。thread间也须要经过协做的方式来完成某些任务。在典型的生产者和消费者场景中。生产者thread在缓冲区已满时须要等待,等消费者thread从缓冲区中取走数据后再进行生产,消费者thread在缓冲区已空时须要等待,等生产者thread向缓冲区放入数据后再进行消费。这种协做方式能够抽象为等待-通知机制。在thread运行时可能须要知足某些条件才能继续进行。当条件不知足时,thread进入等待状态,等待其余thread运行而使条件获得知足。其余thread负责在合适的时机发出通知来唤醒处于等待状态的thread。能够用while循环和volatile变量来处理这个场景。但这种作法本质上是让thread处于忙等待状态,并经过轮询方式来判断条件是否知足。此时thread仍然须要打败cpu时间,会对性能形成影响。更好的作法是使用Object的wait,notify,notifyAll方法。
线程
能够调用任意java对象的wait方法,java中每一个对象除了有与之相关联的监视器对象以外,还有一个与之关联的包含thread的等待集合。在调用wait方法时,该方法调用的接收者所关联的监视器对象是所使用的监视器对象,同时wait方法所影响的是执行wait方法调用的当前thread。因为wait方法的成功调用须要当前thread持有监视器对象上的锁,所以wait方法调用须要放在使用synchronized声明的方法或代码块中。
对象
经过调用wait方法进行等待状态分为无超时和有超时两种。若是thread处于有超时等待状态,则thread能够被主动唤醒而离开等待状态以外,设定的超时时间事后也会自动离开等待状态。在设定超时时间时能够指定毫秒数和纳秒数。
资源
wait方法的做用是使当前thread进行等待状态。对应的notify,notifyall方法用来通知thread离开等待状态。notify会从该对象关联的等待集合中选择一个thread来唤醒。被唤醒的thread和其余thread竞争运行机会。notifyall方法会唤醒相关集合中全部threads。所以当等待集合中可能包含多个threads时,通常使用notifyall方法。
get
须要把wait方法调用置于循环之中。同步
synchronized(obj){
while(/*logic condition 不知足*/){
obj.wait();
}
}
线程状态:
不一样thread状态由枚举类型Thread.State来表示。可能过Thread类的getState方法来获得。它只表示jvm中thread的状态,并不表示对应os上thread的状态。
1 NEW:thread刚被建立出来
2 RUNNABLE:thread处于可运行状态。此时thread有可能正在运行,也有可能在等待其余资源中。
3 BLOCKED:thread在等待一个监视器对象上的锁时,处于此状态。当一thread尝试执行声明为synchronized方法或代码块,又没法获取对应的锁时,处于此状态。
4 WAITING:调用某些方法会使当前thread进入等待状态。这个等待没有超时时间,处于此状态的thread等待其余thread执行特定操做来使当前thread退出等待状态。
5 TIMED_WAITING:此状态相似于4状态,可是增长了指定的超时时间。当超时时间过去,但thread等待的条件仍然没有发生,则thread也会退出等待状态。
6 TERMINATED:thread的运行已终止。
thread在同一时刻只能处于上述6种状态中的一种。