等待/通知机制
wait()方法
- wait()方法是Object类的方法,使当前正在执行的线程等待
- 调用wait方法前,线程必须获得对象的锁,必须在同步方法或同步块中调用wait方法
- 执行wait方法后,线程释放锁
- 如果调用wait时,线程没有持有锁则抛出IllegalMonitorStateException
notify()方法
- notify()方法是Object类的方法,唤醒一个等待状态的线程
- 调用notify方法前,线程必须获得对象的锁,必须在同步方法或同步块中调用notify方法
- 执行notify方法后,线程不会马上释放锁,要等执行notify方法的线程退出synchronized块后才释放锁
- 如果调用notify时,线程没有持有锁则抛出IllegalMonitorStateException
- notify()方法只能唤醒一个线程,如果notify方法调用的次数小于线程对象的数量,会出现部分线程无法唤醒的情况
- 使用notifyAll()方法可以唤醒所有线程
package ch03.test1;
/*
wait()方法和notfy()方法的使用
*/
class MyThread1 extends Thread {
private Object lock;
public MyThread1(Object lock) {
this.lock = lock;
}
@Override
public void run() {
super.run();
synchronized (lock) {
try {
System.out.println("开始wait time=" + System.currentTimeMillis());
lock.wait();
System.out.println("结束wait time=" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread2 extends Thread {
private Object lock;
public MyThread2(Object lock) {
this.lock = lock;
}
@Override
public void run() {
super.run();
synchronized (lock) {
System.out.println("开始notify time=" + System.currentTimeMillis());
lock.notify();
System.out.println("结束notify time=" + System.currentTimeMillis());
}
}
}
public class Test1 {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
MyThread1 myThread1 = new MyThread1(lock);
myThread1.start();
Thread.sleep(3000);
MyThread2 myThread2 = new MyThread2(lock);
myThread2.start();
}
}
就绪和阻塞
线程进入Runable状态的情况
- 调用start()方法
- 调用sleep()方法超过指定的时间
- 线程调用的阻塞IO完毕,阻塞方法返回
- 线程获得了试图同步的监视器
- 线程获得了正在等待的通知
线程进入Blocked状态的情况
- 调用start()方法
- 调用阻塞IO方法
- 线程试图获得同步监视器,但是该监视器被其他线程占有
- 线程等待某个通知