Java Thread:(2) wait() and notif
2021-04-29 本文已影响0人
戈壁堂
Java Thread:(1) synchronization
中的实现版本使用sleep
方法进行等待,造成了CPU的浪费。使用wait()
和notify()
机制优化如下——
public class BusyFlag {
protected Thread busyflag = null;
protected int busycount = 0;
public synchronized void getBusyFlag() {
while (!tryGetBusyFlag()) {
try {
wait();
} catch (Exception e) {}
}
}
public synchronized boolean tryGetBusyFlag() {
if (busyflag == null) {
busyflag = Thread.currentThread();
busycount = 1;
return true;
}
if (busyflag == Thread.currentThread()) {
busycount++;
return true;
}
return false;
}
public synchronized void freeBusyFlag() {
if (getBusyFlagOwner() == Thread.currentThread()) {
busycount--;
if (busycount == 0) {
busyflag = null;
notify();
}
}
}
public synchronized Thread getBusyFlagOwner() {
return busyflag;
}
}
-
getBusyFlagOwner()
方法也添加了同步操作,因为wait()
方法必须在同步方法中调用 -
wait()
和notify()
方法都必须要在同步方法中调用(或使用相同锁对象的同步代码块)。前者表示“需要等待某个条件发生”;后者表示“等待的条件已经发生” -
wait()
在同步方法中调用,似乎永远占据了对象锁,导致其他同步方法无法执行。实际上,在执行wait()
前,将释放锁,然后进入wait状态;条件满足后(notify()
调用后,)wait
方法返回前,重新获取到对象锁。 - 实际上,Java并没有提供获取锁、释放锁的API,
wait()
方法是本地方法,与同步操作紧密结合。这样从外部看,似乎是wait()
方法一直占据着锁 - 如果
notify()
方法调用时,没有wait()
方法调用,立即返回即可,不会有副作用
在内部实现上,wait()
和notify()
通常都是通过控制变量来实现的。所以这要求对这两个方法的调用需要加锁,确保内部对变量的操作是原子的。