如何用管道实现线程间多次通信,不是一次

问题描述

最近看到管道这里,自己写了个用管道来实现两个线程通信的程序,但是不知道为什么第一次通信可以成功,写线程可以写入,读线程可以读出,第二次就出现异常,异常信息是Readenddead。看网上很多人讲是因为第二次通信时读线程已经死亡。请问如何能够用管道实现多次通信?

解决方案

解决方案二:
while能解决吗不过我发现用管道流在两个线程间来回传递数据,效率非常低,不知道的还以为加了延迟
解决方案三:
我就是想知道你是怎么实现的。。代码。。。就像我说我的代码总是报异常空指针一样,你知道大体上为什么会出错,但是你肯定不会知道哪里出的错。。
解决方案四:
引用2楼AA5279AA的回复:

我就是想知道你是怎么实现的。。代码。。。就像我说我的代码总是报异常空指针一样,你知道大体上为什么会出错,但是你肯定不会知道哪里出的错。。

不好意思,不太熟悉CSDN的规则,我的代码如下:

importjava.io.*;importjava.util.Random;classproducerextendsThread{DataOutputStreamd1;inti=0;Randomr=newRandom();producer(OutputStreamout){d1=newDataOutputStream(out);}publicvoidrun(){//System.out.println("producer");try{while(i<10){doublenum=r.nextDouble()*10;System.out.println("thenumis"+num);d1.writeDouble(num);d1.flush();i++;sleep(500);}}catch(IOExceptione){System.out.println("thisisaoutputIOExecption");e.printStackTrace();}catch(InterruptedExceptione){System.out.println("thisisainterruprException");//e.printStackTrace();}}}classconsumerextendsThread{DataInputStreamd2;intcount=0;doublesum=0;consumer(InputStreamin){d2=newDataInputStream(in);}publicvoidrun(){try{doublenum=d2.readDouble();sum+=num;count++;System.out.println("sumis"+sum);sleep(1000);}catch(IOExceptione){System.out.println("thisisainputIOException");e.printStackTrace();}catch(InterruptedExceptione){e.printStackTrace();}}}publicclassPiple{publicstaticvoidmain(String[]args){try{PipedInputStreamp1=newPipedInputStream();PipedOutputStreamp2=newPipedOutputStream(p1);producerp=newproducer(p2);consumerc=newconsumer(p1);p.start();c.start();Thread.sleep(5000);p.stop();c.stop();}catch(IOExceptione){System.out.println("thisismainfunctionException1");e.printStackTrace();}catch(InterruptedExceptione){}}}
解决方案五:
中间consumer的延迟也是500,我改过代码,忘记改这里了,但是修改过以后还是会出现:java.io.IOException:Readenddead的问题,初学JAVA,麻烦各位帮我一下。
解决方案六:
刚学会贴代码,我的代码是这样的:importjava.io.*;importjava.util.Random;classproducerextendsThread{DataOutputStreamd1;inti=0;Randomr=newRandom();producer(OutputStreamout){d1=newDataOutputStream(out);}publicvoidrun(){//System.out.println("producer");try{while(i<10){doublenum=r.nextDouble()*10;System.out.println("thenumis"+num);d1.writeDouble(num);d1.flush();i++;sleep(500);}}catch(IOExceptione){System.out.println("thisisaoutputIOExecption");e.printStackTrace();}catch(InterruptedExceptione){System.out.println("thisisainterruprException");//e.printStackTrace();}}}classconsumerextendsThread{DataInputStreamd2;intcount=0;doublesum=0;consumer(InputStreamin){d2=newDataInputStream(in);}publicvoidrun(){try{doublenum=d2.readDouble();sum+=num;count++;System.out.println("sumis"+sum);sleep(500);}catch(IOExceptione){System.out.println("thisisainputIOException");e.printStackTrace();}catch(InterruptedExceptione){e.printStackTrace();}}}publicclassPiple{publicstaticvoidmain(String[]args){try{PipedInputStreamp1=newPipedInputStream();PipedOutputStreamp2=newPipedOutputStream(p1);producerp=newproducer(p2);consumerc=newconsumer(p1);p.start();c.start();Thread.sleep(5000);p.stop();c.stop();}catch(IOExceptione){System.out.println("thisismainfunctionException1");e.printStackTrace();}catch(InterruptedExceptione){}}}

解决方案七:
同问,,,也是只能读写一次,就抛出异常了:java.io.IOException:Readenddead.
解决方案八:
importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.io.PipedInputStream;importjava.io.PipedOutputStream;importjava.util.Random;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;classproducerextendsThread{DataOutputStreamd1;inti=0;Randomr=newRandom();producer(OutputStreamout){d1=newDataOutputStream(out);}publicvoidrun(){try{while(!Thread.interrupted()){synchronized(d1){if(i<10){doublenum=r.nextDouble()*10;System.out.println("thenumis"+num);d1.writeDouble(num);d1.flush();i++;sleep(500);}else{Thread.yield();}}}}catch(IOExceptione){System.out.println("thisisaoutputIOExecption");e.printStackTrace();}catch(InterruptedExceptione){System.out.println("thisisainterruprException");//e.printStackTrace();}}}classconsumerextendsThread{DataInputStreamd2;intcount=0;doublesum=0;consumer(InputStreamin){d2=newDataInputStream(in);}publicvoidrun(){try{while(!Thread.interrupted()){synchronized(d2){if(d2.available()>0){doublenum=d2.readDouble();sum+=num;count++;System.out.println("sumis"+sum);sleep(500);}else{Thread.yield();}}}}catch(IOExceptione){System.out.println("thisisainputIOException");e.printStackTrace();}catch(InterruptedExceptione){System.out.println("thisisainterruprException");}}}publicclassPiple{publicstaticvoidmain(String[]args){PipedInputStreamp1=null;PipedOutputStreamp2=null;ExecutorServiceexec=Executors.newCachedThreadPool();try{p1=newPipedInputStream();p2=newPipedOutputStream(p1);producerp=newproducer(p2);consumerc=newconsumer(p1);exec.execute(p);exec.execute(c);Thread.sleep(5000);}catch(IOExceptione){System.out.println("thisismainfunctionException1");e.printStackTrace();}catch(InterruptedExceptione){System.out.println("thisismainInterruptedException1");e.printStackTrace();}finally{if(p1!=null){try{p1.close();}catch(IOExceptione){e.printStackTrace();}}if(p2!=null){try{p2.close();}catch(IOExceptione){e.printStackTrace();}}}exec.shutdownNow();}}

改了一下,跑下看看
解决方案九:
引用6楼fhw10204130的回复:

同问,,,也是只能读写一次,就抛出异常了:java.io.IOException:Readenddead.

我擦,陈年老贴,挖坟可耻
解决方案十:
引用8楼zsyhnxc的回复:

Quote: 引用6楼fhw10204130的回复:
同问,,,也是只能读写一次,就抛出异常了:java.io.IOException:Readenddead.

我擦,陈年老贴,挖坟可耻

哈哈

时间: 2025-01-20 23:14:03

如何用管道实现线程间多次通信,不是一次的相关文章

Java中利用管道实现线程间的通讯

在Java 语言中,提供了各种各样的输入输出流(stream),使我们能够很方便的对数据进行操作,其中,管道(pipe)流是一种特殊的流,用于在不同线程(threads)间直接传送数据.一个线程发送数据到输出管道,另一个线程从输入管道中读数据.通过使用管道,实现不同线程间的通讯.无需求助于类似临时文件之类的东西.本文在简要介绍管道的基本概念后,将以一个具体的实例pipeapp加以详细说明. 1.管道的创建与使用 Java提供了两个特殊的专门的类专门用于处理管道,它们就是pipedinputstr

通过管道进行线程间通信:字节流。字符流的用法及API类似

管道流(PipedStream)可以用于不同线程间直接传送数据.一个线程发送数据到输出管道,另一个线程从输入管道中读取数据.通过使用管道,实现不同线程间的通信,而无须借助于类似临时文件之类的东西. package thread.communicate; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; /*2015-11-19*/ public class

多线程编程之三——线程间通讯

七.线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明. 使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量.对于标准类型的全局变量,我们建议使用volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄

JAVA线程间协作:wait.notify.notifyAll

    JAVA的进程同步是通过synchronized()来实现的,需要说明的是,JAVA的synchronized()方法类似于操作系统概念中的互斥内存块,在JAVA中的Object类型中,都是带有一个内存锁的,在有线程获取该内存锁后,其它线程无法访问该内存,从而实现JAVA中简单的同步.互斥操作.明白这个原理,就能理解为什么synchronized(this)与synchronized(static XXX)的区别了,synchronized就是针对内存区块申请内存锁,this关键字代表类

多线程编程之 ---线程间通讯

下载源代码 七.线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明. 使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量.对于标准类型的全局变量,我们建议使用volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将

C++多线程编程(三)线程间通信

多线程编程之三--线程间通讯 作者:韩耀旭 原文地址:http://www.vckbase.com/document/viewdoc/?id=1707   七.线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明. 使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间

线程间共享数据无需竞争

原文 地址  作者  Trisha   译者:李同杰 LMAX Disruptor 是一个开源的并发框架,并获得2011 Duke's程序框架创新奖.本文将用图表的方式为大家介绍Disruptor是什么,用来做什么,以及简单介绍背后的实现原理. Disruptor是什么? Disruptor 是线程内通信框架,用于线程里共享数据.LMAX 创建Disruptor作为可靠消息架构的一部分并将它设计成一种在不同组件中共享数据非常快的方法. 基于Mechanical Sympathy(对于计算机底层硬

Java线程间通讯概述

这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不 用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列 .消息.事件或任何其他并发专用的术语或工具. 只用普通的老式Java接口实现POJO的通讯. 它可能跟Akka的类型化actor类似,但作为一个必须超级轻量,并且要针对单台多核计算机进行优化的 新框架,那个可能有点过了. 当actor跨越不同JVM实例(在同一台机器上,或分布在网络上的不同机器上)的进程边界时,

什么是.Net的异步机制(线程间通信)

前几篇文章我已经对异步的操作进行的详细的解释.异步操作也是线程的一种,当我们开始一个异步操作(新线程),完成调用后需要和其他线程通信(可能需要告知状态信息),这时候我们就需要线程间的通信编程. 线程间通信 我们看下面的图 图1 我们来看线程间通信的原理:线程(Thread B)和线程(Thread A)通信, 首先线程A 必须实现同步上下文对象(Synchronization Context), 线程B通过调用线程A的同步上下文对象来访问线程A,所有实现都是在同步上下文中完成的.线程B有两种方式