线程wait与notify的使用

  1. wait 释放当前锁,让出cpu资源,使当前线程等待.使用场景为先通过synchronized获取锁之后,在该同步代码块中使用wait()方法.
  2. notify与notifyAll 在一个同步代码段中唤醒一个或多个处于等待的线程,在同步代码结束或遇到wait()释放当前锁

    区别:

     notify: 唤醒一个等待的线程,若存在多个则取决于操作系统的多线程管理(会唤醒其中一个)
    	
     notifyAll: 唤醒所有的等待线程,优先级同样取决于操作系统
    
  3. 当线程被唤醒时,wait()方法之后的逻辑继续开始执行

  4. 若未加锁进行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();
        }
    }

}