一、原理:
1、当thread0获得ojb的Monitor锁时,发现不满足条件,进入WaitSet变为WAITTING状态;
2、BLOCKED和WAITING状态的线程都是阻塞状态,不占用cpu;两者是由区别的,WAITING是已经获得过锁,但是又放弃了锁;BLOCKED是正在等待去获取锁;
3、owner线程释放锁时,会唤醒EntryList中的BLOCKED状态的线程;ower线程调用notify或notifyAll方法时会唤醒WaitSet中的线程,让其进入READY就绪状态;
二、使用
obj.wait();让进入object监视器的线程进入WaitSet等待;
obj.notify();从object监视器的WaitSet中挑一个线程唤醒,让其进入就绪状态;
obj.notifyAll();将object监视器的WaitSet中全部线程唤醒;
他们都是线程之间进行协调的手段,都是属于Object对象的方法,所以必须先获得obj的锁,才能调用obj的这几个方法。
sleep和wait的区别:
sleep是Thread的静态方法,wait是Object类的实例方法;
sleep不需要和synchronized配合使用,wait需要;
sleep不会释放对象的锁,wait会释放锁;
公共点:调用两种方法之后,线程都是进入timed_waiting状态。
实战:
notify只能唤醒某一个不确定的线程,所以可能造成虚假唤醒(小南线程被唤醒,但是条件依然不满足),所以需要使用notifyAll方法全部唤醒。
同步模式之保护性暂停:一个线程等待另一个线程的执行结果。
import java.util.concurrent.TimeUnit;
public class Test01 {
public static void main(String[] args) {
MyGuardedObject myGuardedObject = new MyGuardedObject();
new Thread(() -> {
System.out.println("等待t2的执行结果");
Object result = myGuardedObject.get();
System.out.println("等待的结果:" + result);
}, "t1").start();
new Thread(() -> {
System.out.println("执行线程t2.。。。");
String result = "t1需要的结果";
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
myGuardedObject.complete(result);
}, "t2").start();
}
}
class MyGuardedObject{
private Object response;
public Object get() {
synchronized (this) {
while (response == null) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
return response;
}
}
public void complete(Object response) {
synchronized (this) {
this.response = response;
this.notifyAll();
}
}
}
对比join的方式,这种通过共同关联一个第三方对象的方式更加灵活。
park和unpark:
park和unpark方法是LockSupport的静态方法,作用是暂停线程,线程进入waiting状态,unpark唤醒线程,使线程从waiting进入就绪状态。
park方法可以在unpark之后调用,也就是先unpark了,后面再执行park时,unpark的唤醒效果还可以起作用:
原理解析:每个线程都有一个自己的Parker对象,其中有一个counter属性,默认值为0,线程调用park方法时,检查counter是否为0,是的话进入等待状态,调用unpark方法则线程会将counter变量值设为1(扩展一点,unpark可以多次调用,效果只是将counter设为1),同时唤醒等待的线程。如果线程正在运行,先调用unpark方法,counter值变为1,线程不受影响,继续运行,然后调用park方法,这时线程会检查counter的值,发现counter=1,这时的操作是将counter置为0,然后继续运行。
对比wait、notify,park、unpark不用配合synchronized锁来使用,所以更加灵活;
unpark可以精确唤醒某一个线程,notify不能;
原文:https://www.cnblogs.com/dust-to-dust/p/14687817.html