生产者和消费者线程之间的线程间通信?

Interthread communication between producer and consumer threads?

我正在尝试学习使用 BlockingQueue 的线程间通信。

我写了一个生成 TaskId 并将其插入 BlockingQueue 的生产者。

现在我有 2 个消费者线程(名称为“1”和“0”)。如果 taskId 为奇数,则由线程 "1" else "2" 使用。

@Override
    public void run() {
        while (true) {

                while (queue.peek() != null && !name.equals(String.valueOf(queue.peek().intValue() % 2 ))) {

                try {
                    System.out.println(name + ",consumed," + queue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();

                }
            }
        }
    }

我怎样才能在这里进行检查?

我想到的一种方式,还有其他更好的方式:

@Override
    public void run() {
        String name = Thread.currentThread().getName();
        while (true) {

            while (queue.peek() == null) {
                //some sleep time
            }

            synchronized (lock) {
                while (queue.peek() != null && !name.equals(String.valueOf(queue.peek().intValue() % 2 ))) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(queue.peek() != null) {
                    try {
                        System.out.println(name + ",consumed," + queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.notify();
            }
        }
    }

另一种方式:拥有另一个锁,每当元素添加到队列时生产者线程都会通知它。

@Override
    public void run() {
        String name = Thread.currentThread().getName();
        while (true) {

            synchronized (anotherLock) {
                while (queue.peek() == null) {
                    anotherLock.wait();
                }
            }

            synchronized (lock) {
                while (queue.peek() != null && !name.equals(String.valueOf(queue.peek().intValue() % 2 ))) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(queue.peek() != null) {
                    try {
                        System.out.println(name + ",consumed," + queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.notify();
            }
        }
    }