【问题标题】:How to make thread communication using deque?如何使用双端队列进行线程通信?
【发布时间】:2015-01-19 06:07:06
【问题描述】:

我编写了一个程序,其中一个线程用于将元素插入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 停止显示 No elements in queue。我没有得到我做错的地方,谁能告诉我如何解决它。告诉我有没有更好的方法来做到这一点?

【问题讨论】:

    标签: java multithreading deque


    【解决方案1】:

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

    首先在消费者的 run 方法中尝试一些东西,然后根据需要对其进行微调:

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

    【讨论】:

    • 哦,谢谢。 . .我的确切要求是显示队列中最后插入的元素。 .
    • @Raghu:那我看不到两个线程的使用。它将不必要地使代码复杂化。您必须添加一个布尔变量来检查生产者是否已完成,然后才能在消费者运行时从消费者那里获取实际的最后一个元素。
    • 非常感谢,小疑问,我不想在无限循环中执行ReadingThread,我想要一个条件来阻止它,我该怎么做,我用i&lt;deque.size()做了,但没有工作
    • 这是后续问题。如果你认为这个答案是你所需要的,那就接受它,这样它就可以关闭并提出一个新的
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-10
      • 2011-04-02
      • 2023-03-28
      • 2020-06-11
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多