notify"死锁"

459 阅读1分钟

之前找工作时,面试写了个生产者消费者,其中用到了wait notify写完面试官问我你知道notify会产生死锁么?

我当时根本没明白,就一把锁怎么能产生死锁? 最后实际上的意思是所有的线程会进入锁的wait set等待池。

jstack看到的效果如下

代码如下:

package com.huo.learn.thread.pc;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class NotifyHang {
    private static final Object lock = new Object();
    private static int count = 0;
    private static final int MAX = 1;

    private static void produce() {
        synchronized (lock) {
            while (count == MAX) {
                try {
                    log.info(Thread.currentThread().getName() + " wait");
                    lock.wait();
                    log.info(Thread.currentThread().getName() + " wake up");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            count++;
            log.info(Thread.currentThread().getName() + " produce");
            lock.notify();
        }
    }

    private static void consume() {
        synchronized (lock) {
            while (count == 0) {
                try {
                    log.info(Thread.currentThread().getName() + " wait");
                    lock.wait();
                    log.info(Thread.currentThread().getName() + " wake up");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            count--;
            log.info(Thread.currentThread().getName() + " consume");
            lock.notify();
        }
    }

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                produce();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "生产者1").start();
        new Thread(() -> {
            while (true) {

                produce();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "生产者2").start();
        new Thread(() -> {
            while (true) {

                consume();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "消费者1").start();
        new Thread(() -> {
            while (true) {

                consume();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "消费者2").start();
    }

}