生产者线程和使用者线程之间的线程间通信?

时间:2019-10-02 06:39:05

标签: java multithreading wait notify

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

我写了一个生成器,它生成TaskId并将其插入BlockingQueue。

现在我有2个使用者线程(名称“ 1”和“ 0”)。如果taskId为奇数,则由线程“ 1”消耗,否则为“ 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();

                }
            }
        }
    }

我怎么也可以在这里做支票?

1 个答案:

答案 0 :(得分:0)

我正在思考的一种方式,还有其他更好的方式:

@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();
            }
        }
    }

另一种方法:拥有将在元素添加到队列时由生产者线程通知的anotherLock。

@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();
            }
        }
    }