首先对于类的归属:wait是Object的方法,而sleep属于Thread。在执行sleep时,其线程会停止执行相应时间,但其线程的监控器并不会停止监控,即线程不会释放锁,一段时间过后线程会自动恢复运行。而执行wait方法的线程在执行此方法后会马上进入线程的等待队列,成为阻塞态,直至此对象再次执行notify方法时,才会进入线程锁定池进入就绪态。
测试:
/**
*
* @ClassName: Service
* @Description: 这里将notify和wait方法都写在这个类中,写在类中是为了熟悉wait和notify的用法 <br>
* wait必须是监视器来调用,且必须在同步块(synchronized)中使用,notify同,原因<br>
* 为何会在下一篇博客中提到
* @author: 邓盛哲
* @date: 2019年2月20日 上午12:06:18
*
*/
public class Service {
public void testWait(Object lock) {
synchronized (lock) {
try {
lock.wait();
System.out.println(Thread.currentThread().getName() + " is waiting");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void testNotify(Object lock) {
synchronized (lock) {
lock.notify();
System.out.println(Thread.currentThread().getName() + " is notified");
}
}
}
线程A使用wait方法,在一秒钟后wait
public class TestWaitClass extends Thread {
private Object lock;
public TestWaitClass() {
}
public TestWaitClass(Object lock) {
this.lock = lock;
}
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() + " is runing");
try {
Service service = new Service();
Thread.sleep(1000);
service.testWait(lock);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程B只使用sleep
public class AnoTestWaitClass extends Thread {
// private Object lock;
// public AnoTestWaitClass(Object lock) {
// this.lock = lock;
// }
@Override
public void run() {
while(true) {
try {
// Service service = new Service();
System.out.println(Thread.currentThread().getName() + " is running");
Thread.sleep(800);
// service.testNotify(lock);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出
Thread-0 is runing
Thread-1 is running
Thread-1 is running
在执行了testWait后,thread-0主动释放锁进入锁定池,等待其他线程执行了lock的notify后才会对其进行唤醒,然而并没有其他对象进行唤醒,所以一直处于wait状态。而thread-0只是让线程暂停了millis时长,并未放弃监视器,所以可以得到此输出。