一、管道流是JAVA中线程通讯的常用方式之一,基本流程如下:

1)创建管道输出流PipedOutputStream pos和管道输入流PipedInputStream pis

2)将pos和pis匹配,pos.connect(pis);

3)将pos赋给信息输入线程,pis赋给信息获取线程,就可以实现线程间的通讯了

package wyf;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream; public class testPipeConnection { public static void main(String[] args) {
/**
* 创建管道输出流
*/
PipedOutputStream pos = new PipedOutputStream();
/**
* 创建管道输入流
*/
PipedInputStream pis = new PipedInputStream();
try {
/**
* 将管道输入流与输出流连接 此过程也可通过重载的构造函数来实现
*/
pos.connect(pis);
} catch (IOException e) {
e.printStackTrace();
}
/**
* 创建生产者线程
*/
Producer p = new Producer(pos);
/**
* 创建消费者线程
*/
Consumer1 c1 = new Consumer1(pis);
/**
* 启动线程
*/
p.start();
c1.start();
}
} /**
* 生产者线程(与一个管道输入流相关联)
*
*/
class Producer extends Thread {
private PipedOutputStream pos; public Producer(PipedOutputStream pos) {
this.pos = pos;
} public void run() {
int i = 0;
try {
while(true)
{
this.sleep(3000);
pos.write(i);
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
} /**
* 消费者线程(与一个管道输入流相关联)
*
*/
class Consumer1 extends Thread {
private PipedInputStream pis; public Consumer1(PipedInputStream pis) {
this.pis = pis;
} public void run() {
try {
while(true)
{
System.out.println("consumer1:"+pis.read());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

程序启动后,就可以看到producer线程往consumer1线程发送数据

consumer1:0
consumer1:1
consumer1:2
consumer1:3

......

二、管道流的缺点:

管道流虽然使用起来方便,但是也有一些缺点

1)管道流只能在两个线程之间传递数据

package wyf;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class testPipeConnection { public static void main(String[] args) {
/**
* 创建管道输出流
*/
PipedOutputStream pos = new PipedOutputStream();
/**
* 创建管道输入流
*/
PipedInputStream pis = new PipedInputStream();
try {
/**
* 将管道输入流与输出流连接 此过程也可通过重载的构造函数来实现
*/
pos.connect(pis);
} catch (IOException e) {
e.printStackTrace();
}
/**
* 创建生产者线程
*/
Producer p = new Producer(pos);
/**
* 创建消费者线程
*/
Consumer1 c1 = new Consumer1(pis); Consumer2 c2 = new Consumer2(pis);
/**
* 启动线程
*/
p.start();
c1.start();
c2.start();
}
} /**
* 生产者线程(与一个管道输入流相关联)
*
*/
class Producer extends Thread {
private PipedOutputStream pos; public Producer(PipedOutputStream pos) {
this.pos = pos;
} public void run() {
int i = 0;
try {
while(true)
{
this.sleep(3000);
pos.write(i);
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
} /**
* 消费者线程(与一个管道输入流相关联)
*
*/
class Consumer1 extends Thread {
private PipedInputStream pis; public Consumer1(PipedInputStream pis) {
this.pis = pis;
} public void run() {
try {
while(true)
{
System.out.println("consumer1:"+pis.read());
}
} catch (IOException e) {
e.printStackTrace();
}
}
} class Consumer2 extends Thread {
private PipedInputStream pis; public Consumer2(PipedInputStream pis) {
this.pis = pis;
} public void run() {
try {
while(true)
{
System.out.println("consumer2:"+pis.read());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

程序启动后输出如下:

consumer1:0
consumer1:1
consumer1:2
consumer1:3
consumer2:4
consumer2:5
consumer1:6

......

线程consumer1和consumer2同时从pis中read数据,当线程producer往管道流中写入一段数据后,每一个时刻只有一个线程能获取到数据,并不是两个线程都能获取到producer发送来的数据,因此一个管道流只能用于两个线程间的通讯。不仅仅是管道流,其他IO方式都是一对一传输。

2)管道流只能实现单向发送,如果要两个线程之间互通讯,则需要两个管道流

可以看到上面的例子中,线程producer通过管道流向线程consumer发送数据,如果线程consumer想给线程producer发送数据,则需要新建另一个管道流pos1和pis1,将pos1赋给consumer1,将pis1赋给producer,具体例子本文不再多说。

总结:

可以看到管道流使用起来很方便,但是制约也很大,具体使用要看实际的需求,如果项目中只有两个线程持续传递消息,那用管道流也很方便,如果项目中有很多个线程之间需要通讯,那还是用共享变量的方式来传递消息比较方便。

Java 线程间通讯(管道流方式)的更多相关文章

  1. Java 线程间通讯(共享变量方式)

    Java线程间通讯,最常用的方式便是共享变量方式,多个线程共享一个静态变量就可以实现在线程间通讯,但是这需要注意的就是线程同步问题. 一.没考虑线程同步: package com.wyf; publi ...

  2. Java 线程间通讯

    /* 线程间通讯: 多个线程在处理同一资源,但是任务却不同. */ package com.cwcec.test; class Input implements Runnable { Resource ...

  3. JMM之Java线程间通讯——等待通知机制及其经典范式

    在并发编程中,实际处理涉及两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体). 通信是指线程之间以何种机制来交换信息.在共享内存的并发模型里,线程之间共享程序的公共状 ...

  4. java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...

  5. 黑马程序员——JAVA基础之多线程的线程间通讯等

    ------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...

  6. (转载)Java里快如闪电的线程间通讯

    转自(http://www.infoq.com/cn/articles/High-Performance-Java-Inter-Thread-Communications) 这个故事源自一个很简单的想 ...

  7. Java中快如闪电的线程间通讯

    这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...

  8. Java 里快如闪电的线程间通讯

    这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...

  9. 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...

随机推荐

  1. SmartAdmin 打开速度慢的原因

    最近在使用SmartAdmin做个小东西,发布在公网上,我的机器打开飞快,但是到了其它人的机器上变得极慢了.而且在我的手机上也打开变慢.     查找原因,原来如此.      <link re ...

  2. 深入认识JavaScript 中的this指针

    深入认识JavaScript 中的this指针this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象.在实现对象的方法时,可以使用this指针来获得该对象自身的引用.和传统意义的面向对象 ...

  3. linux系统下搭建php环境之-Discuz论坛

    1.安装搭建论坛必要的软件 apache php mysql CentOS系统我们可以直接使用 yum install 的方式进行软件安装,腾讯云有提供软件安装源,是同步CentOS官方的安装源,包涵 ...

  4. RSA加密工具包

    主要参考: http://www.blogjava.net/icewee/archive/2012/05/19/378570.html http://snowolf.iteye.com/ 基于以上代码 ...

  5. Slow HTTP Denial of Service Attack

    整改建议 1.中断使用URL不支持HTTP方法访问的会话 2.限制HTTP头及包长至一个合理数值 3.设置一个绝对的会话超时时间 4.服务器支持backlog的情况下,需设置一个合理的大小 5.设置一 ...

  6. C#分析搜索引擎URL得到搜索关键字,并判断页面停留时间以及来源页面

    前台代码: var start; var end; var state; var lasturl = document.referrer; start = new Date($.ajax({ asyn ...

  7. 【python】环境变量的配置

    在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1.首先需要在系统中注册python环境变量:假设python的安装路径为c:\p ...

  8. (转)VS.NET2010水晶报表安装部署[VS2010]

    本文转载自:http://www.cnblogs.com/xiaofengfeng/p/3325793.html 欢迎C#高手加盟QQ群:9340166 水晶报表VS2010版IDE安装标准版SAP ...

  9. SQLite加密的方法(c#)

    http://blog.csdn.net/xjbx/article/details/2712236 设置下密码就可以了 http://bbs.csdn.net/topics/380018685 编译为 ...

  10. 黄聪:发送键盘指令System.Windows.Forms.SendKeys.Send

    若要指定在按键(如 Enter 或 Tab)时不显示的字符,以及表示操作而不表示字符的键,请使用下表中的代码:   键 代码 Backspace {BACKSPACE}.{BS} 或 {BKSP} B ...