线程wait与notify的使用
- wait
释放当前锁,让出cpu资源,使当前线程等待.使用场景为先通过synchronized获取锁之后,在该同步代码块中使用
wait()
方法. -
notify与notifyAll 在一个同步代码段中唤醒一个或多个处于等待的线程,在同步代码结束或遇到
wait()
释放当前锁区别:
notify: 唤醒一个等待的线程,若存在多个则取决于操作系统的多线程管理(会唤醒其中一个) notifyAll: 唤醒所有的等待线程,优先级同样取决于操作系统
-
当线程被唤醒时,
wait()
方法之后的逻辑继续开始执行 - 若未加锁进行
wait()
或notify()
/notifyAll()
的调用,会抛出IllegalMonitorStateException
举例
poolList
等待生产的num
,若poolList
数量未达到10
则继续等待,达到10
时候进行消费
package temp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class NotifyTest {
private List<Integer> poolList = Collections.synchronizedList(new ArrayList<>());
private void produceAndNotify(int i) {
synchronized (poolList) {
poolList.add(i);
System.out.println("produce num:" + i);
poolList.notify();
}
}
private void consumer() {
int batchSize = 10;
synchronized (poolList) {
while (poolList.size() < batchSize) {
try {
System.out.println("线程即将开始等待...");
poolList.wait();
System.out.println("线程唤醒成功!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费成功:" + poolList);
poolList.clear();
}
consumer();
}
public static void main(String[] args) {
NotifyTest notifyTest = new NotifyTest();
Thread t0 = new Thread(new Runnable() {
@Override
public void run() {
notifyTest.consumer();
}
});
t0.start();
for (int i = 0; i < 50; i++) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
int num = (int) (Math.random() * 1000);
notifyTest.produceAndNotify(num);
}
});
t1.start();
}
}
}