1 wait,notify,notifyAll方法详解
1.1 作用、用法
我们可以通过上面方法控制一些线程去休息或唤醒
当一个线程使用wait方法时,这个线程被阻塞(阻塞阶段)并且释放锁
由阻塞状态变为唤醒阶段有几种情况?
- 另一个线程调用这个对象的notify()方法且刚好被唤醒的是本线程
- 另一个线程调用这个对象的notifyAll()方法
- 过了wait( long timeout )规定的时间,如果传入0就是永久等待
- 线程自身调用了interrupt()
遇到中断会由阻塞状态变为唤醒状态
public static void main (String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run () {
try {
System.out.println("t1 begin sleep 2000 seconds");
Thread.sleep(2000000);
System.out.println("t1 awaking");
} catch (InterruptedException e) {
System.out.println("t1 is interrupted while sleeping");
return;
}
System.out.println("t1 continue working");
}
});
t1.start();
Thread.sleep(1000);
//打断子线程的休眠,让子线程从sleep函数返回
t1.interrupt();
//等待子线程执行完毕
t1.join();
System.out.println("main thread is over");
}
输出
1.2 代码演示
wait演示
public class Wait {
static Object object = new Object();
static class Thread1 extends Thread{
@Override
public void run () {
synchronized (object){
System.out.println("线程"+Thread.currentThread().getName()+"开始执行");
try {
object.wait();//释放了锁,并且将线程t1阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程"+Thread.currentThread().getName()+"释放了锁");
}
}
}
static class Thread2 extends Thread{
@Override
public void run () {
synchronized (object){
object.notify();
System.out.println("线程"+Thread.currentThread().getName()+"调用了notify()");
}
}
}
public static void main (String[] args) throws InterruptedException {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
Thread.sleep(2000);
t2.start();
}
}
输出
线程Thread-0开始执行
线程Thread-1调用了notify()
线程Thread-0释放了锁
描述一下代码执行的整个过程:
- 线程t1得到了锁object,打印出"线程Thread-0开始执行"
- 线程执行到了object.wait()。锁object被释放,线程t1被阻塞
- 线程t2得到了锁object,执行语句object.notify(),此时线程t1被
- 唤醒,但是该线程不能获得锁object。必须要等t2释放了锁之后才能运行
- t1重新获取到锁之后会返回之前的位置,继续执行代码
notifyAll演示
/**
* 线程1和2首先被阻塞,线程3唤醒它们
*/
public class WaitNotifyAll implements Runnable