我编写了一个程序,其中一个线程用于将元素插入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
。我没有得到我做错的地方,任何人都可以告诉我如何解决它。告诉我有没有更好的方法呢?
答案 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给出的代码替换代码。