为了账号安全,请及时绑定邮箱和手机立即绑定

java多线程从队列中取出数据执行

java多线程从队列中取出数据执行

牛魔王的故事 2019-05-25 16:00:40
先用python实现,把每一个要处理的参数存放到队列Queue中,然后创建线程从队列中取出classThreadExecuteJob(threading.Thread):"""ThreadedUrlGrab"""def__init__(self,queue):threading.Thread.__init__(self)self.queue=queuedefrun(self):while1:i=self.queue.get()try:print"执行的参数"+str(i)#发送执行完毕信号self.queue.task_done()exceptExceptionase:logging.warning(str(fun)+"---"+str(e.message)+"---"+str(e.args))defexecute_job_thread_pool(queue):""":paramqueue:队列:paramarg:函数的参数:return:"""foriinxrange(6):t=ThreadExecuteJob(queue)t.setDaemon(True)t.start()if__name__=="__main__":importQueueday_q=Queue.Queue()foriinxrange(6):day_q.put(i)execute_job_thread_pool(day_q)day_q.join()用python实现的多线程取出0-5个数打印出来。现在用java粗略实现的如下,但是队列数据取完了主线程没有停止,如何让主线程停止,如何像python那样队列数据取完主线程也停止publicclassHelloJava8{publicstaticvoidmain(String[]args)throwsInterruptedException{//TODOAuto-generatedmethodstubBlockingQueues=newLinkedBlockingQueue();s.put("java");s.put("python");s.put("php");s.put("c++");s.put("c");ArrayListthreadList=newArrayList();Threadt1=newThread(newConsumer("zhangsan",s));t1.start();threadList.add(t1);Threadt2=newThread(newConsumer("lisi",s));t2.start();threadList.add(t2);Threadt3=newThread(newConsumer("wangwu",s));t3.start();threadList.add(t3);Threadt4=newThread(newConsumer("afei",s));t4.start();threadList.add(t4);Threadt5=newThread(newConsumer("jb",s));t5.start();threadList.add(t5);for(Threadthread:threadList){thread.join();}System.out.println("主线程执行完毕");}}classConsumerimplementsRunnable{privateStringname;privateBlockingQueues=null;publicConsumer(Stringname,BlockingQueues){this.name=name;this.s=s;}publicvoidrun(){try{while(true){Stringproduct=(String)s.take();System.out.println(name+"消费("+product.toString()+").");System.out.println("===============");Thread.sleep(300);}}catch(InterruptedExceptione){e.printStackTrace();}}}
查看完整描述

2 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

Consumer类的run方法中,while的条件应该改为!s.isEmpty()。主线程未能执行结束的原因是子线程都没有结束造成的,因为BlockingQueue.take()造成了阻塞,看一下文档中写的
take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入
也就是说当BlockingQueue中的对象被消费完毕之后,再次调用其take方法,就会进入等待状态,而题主在程序中使用while(true)作为循环条件,则所有的线程都会不断的调用队列的take方法,而进入阻塞状态,无法退出线程,子线程无法退出,则join之后的主线程System.out.println("主线程执行完毕");则永远在等待,无法执行,故主线程也无法退出。
                            
查看完整回答
反对 回复 2019-05-25
  • 2 回答
  • 0 关注
  • 1208 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信