多线程下使用wait和notify为什么写在while里面,而不是if

发布时间 2023-10-30 15:41:15作者: 深夜小码农

多线程下使用wait和notify为什么写在while里面,而不是if?

1、在线程下,wait状态会进入waitset队列等待, 没有抢占到锁的线程synchronized,会进入到entryset队列 等待

2、假设有生产者和消费者。同时有多个生产者生产,多个消费者消费

3、如果是if状态,有一个生产者wait住,一个消费者wait住,另一个消费者已消费完,会notifyAll所有线程,则消费者先抢到锁,那么它会直接进行后续操作,可能这个后续操作的条件并不满足于if条件判断的条件。

4、如果使用while则不会出现这种情况,因为会进行while条件循环判断,满足则执行后续操作

示例代码

/**
 * @Description
 * @Author jackzhang
 */
public class Thread03{

    private Buffer mbuffer = new Buffer();
    // private List<Object> list = new ArrayList<>();

    public void product(){
        synchronized (this) {
            if (mbuffer.isFull()){
                try {
                    wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            mbuffer.add();
            notifyAll();
        }

    }

    public void consumer(){
        synchronized (this) {
            if (mbuffer.isEmpty()){
                try {
                    wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            mbuffer.remove();
            notifyAll();
        }

    }

    private class Buffer {
        private static final int MAX_CAPACITY = 1;
        private List innerList = new ArrayList<>(MAX_CAPACITY);

        void add() {
            if (isFull()) {
                throw new IndexOutOfBoundsException();
            } else {
                innerList.add(new Object());
            }
            System.out.println(Thread.currentThread().toString() + " add");

        }

        void remove() {
            if (isEmpty()) {
                throw new IndexOutOfBoundsException();
            } else {
                innerList.remove(MAX_CAPACITY - 1);
            }
            System.out.println(Thread.currentThread().toString() + " remove");
        }

        boolean isEmpty() {
            return innerList.isEmpty();
        }

        boolean isFull() {
            return innerList.size() == MAX_CAPACITY;
        }
    }

    public static void main(String[] args) {
        Thread03 thread03 = new Thread03();
        Runnable product = new Runnable() {
            int count = 4;

            @Override
            public void run() {
                while (count-- > 0) {
                    thread03.product();
                }

            }
        };

        Runnable consumer = new Runnable(){
            @Override
            public void run() {
                int count = 4;
                while (count-- >0){
                    thread03.consumer();
                }            }
        };

        for (int i = 0; i < 2; i++) {
            new Thread(product).start();
        }

        for (int i = 0; i < 2; i++) {
            new Thread(consumer).start();
        }
    }



}