如何使用deque进行线程通信?

时间:2014-11-21 06:39:08

标签: java multithreading deque

我编写了一个程序,其中一个线程用于将元素插入Deque,另一个用于读取来自同一Deque的元素。为此,我这样做,

public class ThreadCommunicationInDeque {
public static void main(String args[])
{
    Deque deque=new LinkedList<>();
    InsertingThread it=new InsertingThread(deque);
    ReadingThread1 rt=new ReadingThread1(deque);
    it.start();
    rt.start();
}
}

class InsertingThread extends Thread{

Deque deque=new LinkedList<>();
InsertingThread(Deque deque){
    this.deque=deque;
}

@Override
public void run(){
   for(int i=0;i<50;i++){
       try {
           deque.add(i);
           System.out.println(deque.getLast());
           Thread.sleep(100);
       } catch (InterruptedException ex) {
           Logger.getLogger(InsertingThread.class.getName()).log(Level.SEVERE, null, ex);
       }
   }
}

}
class ReadingThread1 extends Thread{

Deque deque=new LinkedList<>();

ReadingThread1(Deque deque){
  this.deque=deque;
}

@Override
public void run(){
    if(deque.isEmpty()){
        System.out.println("No elements in queue");
    }else
    {
        System.out.println(deque.getLast());
        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(ReadingThread1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
}

我的问题是InsertingThread工作正常但ReadingThread停止显示否elements in queue。我没有得到我做错的地方,任何人都可以告诉我如何解决它。告诉我有没有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

那是因为你没有消费者像线程一样在循环中运行。它只运行一次并且看到队列中没有元素(如果说消费者是先运行的线程,则可能是真的),然后从线程安全退出。

首先尝试使用消费者的运行方法,然后根据需要对其进行微调:

while (true) {
        if (deque.isEmpty()) {
            System.out.println("No elements in queue");
        } else {
            System.out.println("consumed " + deque.removeLast());//note get will still have queue populated so remove seems better?
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
            }
        }
}

顺便说一句,您不必在生产者和消费者中创建出列队列的实例。你可以删除实例化,即从

Deque<Integer> deque = new LinkedList<Integer>();

Deque<Integer> deque;

如果你只想显示一个线程中的最后一个元素(你可以从main方法中执行它),那么你可以通过调用如下所示的join方法来实现它(所以它让生产者完成然后启动消费者线程)在你的主要方法中:

public static void main(String args[]) throws InterruptedException {
    Deque<Integer> deque = new LinkedList<Integer>();
    InsertingThread it = new InsertingThread(deque);
    ReadingThread1 rt = new ReadingThread1(deque);
    it.start();
    it.join();
    rt.start();
}

答案 1 :(得分:1)

执行threads的顺序是随机的,无法确定。因此,启动生产者线程it.start()并不意味着在您检索rt. start()之前始终会进行插入。因为你将插入。对于检索,您应该尝试使用almas给出的代码替换代码。