调用sleep()和yield()时,对象的锁是没有被释放的,但调用wait()方法时,线程将被挂起,对象的锁会被释放,这就意味着另一个任务将获得对象的锁。因此,在这个时候,对象中其它被标记为synchronized的方法将可以再wait()期间被调用。
1:wait()期间,对象的锁是释放的。
2:可以通过notify(),notifyAll()或令时间到期(wait()里可以设置参数,若不设置参数将无限等待下去),从wait()中恢复执行。
wait(),notify(),notifyAll()方法时基类Object的一部分。这些方法只能在同步控制方法或同步控制块里调用。否则,在运行时将抛出IllegalMonitorStateException异常。
可以让另一个对象执行某种操作以维护其自己的锁。要这么做的话,必须首先得到对象的锁。比如,如果要向对象x发送notifyAll(),那么就必须在能够取得x的锁的同步控制块中这么做。
synchronized(x){
x.notifyAll();
}
下面是一个模拟为车擦油漆的过程(上漆和抛光)。
class Car{
private boolean waxOn=false;
public synchronized void waxed() {
waxOn=true;
notifyAll();
}
public synchronized void buffed() {
waxOn=false;
notifyAll();
}
public synchronized void waitingForWaxing() throws InterruptedException {
while(waxOn==false)
wait();
}
public synchronized void waitingForbBuffed() throws InterruptedException {
while(waxOn==true)
wait();
}
}
class WaxOn implements Runnable{
private Car car;
public WaxOn(Car car) {
this.car=car;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
while(!Thread.interrupted()) {
System.out.println("Wax On!");
TimeUnit.MILLISECONDS.sleep(200);
car.waxed();
car.waitingForbBuffed();
}
}catch(InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax On task");
}
}
class WaxOff implements Runnable{
private Car car;
public WaxOff(Car car) {
this.car=car;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
car.waitingForWaxing();
System.out.println("Wax Off!");
TimeUnit.MILLISECONDS.sleep(200);
car.buffed();
}catch(InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax Off task");
}
}
public class WaxOMatic {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
Car car=new Car();
ExecutorService exec=Executors.newCachedThreadPool();
exec.execute(new WaxOn(car));
exec.execute(new WaxOff(car));
TimeUnit.MILLISECONDS.sleep(5000);
exec.shutdownNow();
}
}
任务中的TIMEUNIY.MILLISECONDS.sleep()模拟的是上漆或抛光的时间。