wait方法
让线程释放锁并进入等待状态,要搭配
synchronized
关键字使用
我们这里介绍两个wait方法
-
无参的wait
public final void wait() throws InterruptedException
让线程释放锁并进入等待状态,直到被唤醒,我们称为"死等" -
有一个参数的wait方法
public final void wait(long timeout) throws InterruptedException
让线程释放锁并进入等待状态,直到被唤醒或者超过指定的时间
注意:
线程被唤醒后需要重新参与锁竞争,从
wait
方法之后开始执行
notify方法
唤醒等待的线程,要搭配
synchronized
关键字使用
这里同样介绍两个方法
- notify
public final void notify()
唤醒该对象等待的线程,如果存在多个等待的线程,则会随机唤醒一个 - notifyall
public final void notifyAll()
唤醒该对象全部等待的线程
注意:
使用
notify
方法并不会马上释放锁,而是执行完同步代码块才释放锁
使用示例
有三个线程,分别只能打印A,B和C
要求按顺序打印ABC,打印10次
输出示例:
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
使用wait
和notify
就可以很好的解决这个问题
我们先使用wait
方法让三个线程都进入等待状态,通过notify
方法依次唤醒即可
public static void main(String[] args) throws InterruptedException {
Object A=new Object();
Object B=new Object();
Object C=new Object();
Thread a=new Thread(()->{
for (int i=0;i<10;i++) {
synchronized (A) {
try {
A.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print("A");
synchronized (B) {
B.notify();
}
}
});
Thread b=new Thread(()->{
for (int i=0;i<10;i++) {
synchronized (B) {
try {
B.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print("B");
synchronized (C) {
C.notify();
}
}
});
Thread c=new Thread(()->{
for (int i=0;i<10;i++) {
synchronized (C) {
try {
C.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("C");
synchronized (A) {
A.notify();
}
}
});
a.start();
b.start();
c.start();
Thread.sleep(100);
synchronized (A) {
A.notify();
}
}
wait和sleep的区别
wait
是Object
的方法,sleep
是Thread
的静态方法wait
要搭配synchronized
关键字使用,sleep
不用wait
会使线程释放锁并进入等待状态,sleep
是让线程暂停执行指定时间,不会释放资源wait
用于线程间通信,sleep
用于线程阻塞一段时间