保护性暂挂模式(Guarded Suspension Pattern)常用于一个线程等待去另一个线程的结果;
Thread中的join方法就是使用的这一设计模式,主要代码如下:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) { //使用while 防止虚假唤醒
long delay = millis - now; //防止虚假唤醒后的超时等待
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
这里在上面代码基础上做简单修改,实现一个线程等待另一个线程;
public class GuardedTest {
public static void main(String[] args) {
GuardedObject guardedObject = new GuardedObject();
new Thread(()->{
try {
Object o = guardedObject.get(0);
System.out.println(o);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1").start();
new Thread(()->{
try {
Thread.sleep(9000);
} catch (InterruptedException e) {
e.printStackTrace();
}
guardedObject.set(999);
},"t2").start();
}
}
class GuardedObject{
private Object object;
public final synchronized Object get(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (object ==null) {
wait(0);
}
} else {
while (object == null) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
return object;
}
public final synchronized void set(Object object){
this.object = object;
this.notify();
}
}
相关知识点:
synchronized:保证原子性和可见性;
sleep():不释放对象锁:
wait():释放对象锁,可能存在虚假唤醒,需配合synchronized使用;
synchronized修饰方法时,未使用static时,锁对象时当前对象this;