Java wait notify解析

方法/ 作用

wait: 线程自动释放占有的对象锁,并等待notify。
notify: 随机唤醒一个正在wait当前对象的线程,并让被唤醒的线程拿到对象锁
notifyAll: 唤醒所有正在wait当前对象的线程,但是被唤醒的线程会再次去竞争对象锁。因为一次只有一个线程能拿到锁,所有其他没有拿到锁的线程会被阻塞。推荐使用。

Java中规定,在调用这三个方法时,当前线程必须获得对象锁。因此就得配合synchronized关键字来使用。在synchronized拿到对象锁之后,synchronized代码块或者方法中,必定是会持有对象锁的,因此就可以使用wait()或者notify()。

使用wait()、notify()来实现一个生产者、消费者模式:
class ProductAndCusumer {
    private static final Integer MAX_CAPACITY = 5;
    private static LinkedList<String> queue = new LinkedList<>();  //需要将queue作为多线程操作的锁

    static class Producter extends Thread {
        @Override
        public void run() {
            while (true) {
                synchronized (queue) {

                    if (queue.size() >= MAX_CAPACITY * 2) {
                        System.out.println("缓冲队列已满");

                        //停止生产产品,此时在生产者的线程中,调用queue.wait主动去释放锁,
                        //让当前消费线程进入等待唤醒去拿锁
                        try {
                            queue.wait();
                        } catch (Exception e) {
                        }
                    }

                    //没有满,继续生产
                    String product = "生产:" + Thread.currentThread().getName();
                    System.out.println(product);
                    queue.add(product);
                    try {
                        Thread.sleep(500);
                    } catch (Exception e) {

                    }

                    try {
                        queue.notifyAll();  //唤醒所有线程拿锁
                    } catch (Exception e) {
                    }
                }

            }

        }
    }

    static class Consumer extends Thread {
        @Override
        public void run() {
            while (true) {
                synchronized (queue) {
                    if (queue.isEmpty()) {
                        System.out.println("缓冲队列为空,暂无消费产品");
                        try {
                            queue.wait();
                        } catch (Exception e) {
                        }
                    }

                    try {
                        System.out.println("消费:" + queue.pop());
                        Thread.sleep(500);
                        queue.notifyAll();
                    } catch (Exception e) {
                    }

                }

            }
        }
    }

    public static void main(String[] args) {
        new Producter().start();
        new Consumer().start();
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章