实现java线程通信的几种方式 讲解java多线程共享数据( 三 )


但是如果抛出了 InterruptedException 异常 。该标志就会被 JVM 重置为 false 。
线程池 awaitTermination() 方法
如果是用线程池来管理线程 。可以使用以下方式来让主线程等待线程池中所有任务执行完毕:
privatestaticvoidexecutorService()throwsException{BlockingQueue<Runnable>queue=newLinkedBlockingQueue<>(10);ThreadPoolExecutorpoolExecutor=newThreadPoolExecutor(5,5,1,TimeUnit.MILLISECONDS,queue);poolExecutor.execute(newRunnable(){@Overridepublicvoidrun(){LOGGER.info("running");try{Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}}});poolExecutor.execute(newRunnable(){@Overridepublicvoidrun(){LOGGER.info("running2");try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}}});poolExecutor.shutdown();while(!poolExecutor.awaitTermination(1,TimeUnit.SECONDS)){LOGGER.info("线程还在执行 。。。");}LOGGER.info("mainover");}输出结果:
2018-03-1620:18:01.273[pool-1-thread-2]INFOc.c.actual.ThreadCommunication-running22018-03-1620:18:01.273[pool-1-thread-1]INFOc.c.actual.ThreadCommunication-running2018-03-1620:18:02.273[main]INFOc.c.actual.ThreadCommunication-线程还在执行 。。。2018-03-1620:18:03.278[main]INFOc.c.actual.ThreadCommunication-线程还在执行 。。。2018-03-1620:18:04.278[main]INFOc.c.actual.ThreadCommunication-mainover使用这个 awaitTermination() 方法的前提需要关闭线程池 。如调用了 shutdown() 方法 。
调用了 shutdown() 之后线程池会停止接受新任务 。并且会平滑的关闭线程池中现有的任务 。
管道通信
publicstaticvoidpiped()throwsIOException{//面向于字符PipedInputStream面向于字节PipedWriterwriter=newPipedWriter();PipedReaderreader=newPipedReader();//输入输出流建立连接writer.connect(reader);Threadt1=newThread(newRunnable(){@Overridepublicvoidrun(){LOGGER.info("running");try{for(inti=0;i<10;i++){writer.write(i+"");Thread.sleep(10);}}catch(Exceptione){}finally{try{writer.close();}catch(IOExceptione){e.printStackTrace();}}}});Threadt2=newThread(newRunnable(){@Overridepublicvoidrun(){LOGGER.info("running2");intmsg=0;try{while((msg=reader.read())!=-1){LOGGER.info("msg={}",(char)msg);}}catch(Exceptione){}}});t1.start();t2.start();}输出结果:
2018-03-1619:56:43.014[Thread-0]INFOc.c.actual.ThreadCommunication-running2018-03-1619:56:43.014[Thread-1]INFOc.c.actual.ThreadCommunication-running22018-03-1619:56:43.130[Thread-1]INFOc.c.actual.ThreadCommunication-msg=02018-03-1619:56:43.132[Thread-1]INFOc.c.actual.ThreadCommunication-msg=12018-03-1619:56:43.132[Thread-1]INFOc.c.actual.ThreadCommunication-msg=22018-03-1619:56:43.133[Thread-1]INFOc.c.actual.ThreadCommunication-msg=32018-03-1619:56:43.133[Thread-1]INFOc.c.actual.ThreadCommunication-msg=42018-03-1619:56:43.133[Thread-1]INFOc.c.actual.ThreadCommunication-msg=52018-03-1619:56:43.133[Thread-1]INFOc.c.actual.ThreadCommunication-msg=62018-03-1619:56:43.134[Thread-1]INFOc.c.actual.ThreadCommunication-msg=72018-03-1619:56:43.134[Thread-1]INFOc.c.actual.ThreadCommunication-msg=82018-03-1619:56:43.134[Thread-1]INFOc.c.actual.ThreadCommunication-msg=9Java 虽说是基于内存通信的 。但也可以使用管道通信 。
需要注意的是 。输入流和输出流需要首先建立连接 。这样线程 B 就可以收到线程 A 发出的消息了 。
实际开发中可以灵活根据需求选择最适合的线程通信方式 。

推荐阅读