Java 线程间通讯(管道流方式)
一、管道流是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 线程间通讯(管道流方式)的更多相关文章
- Java 线程间通讯(共享变量方式)
Java线程间通讯,最常用的方式便是共享变量方式,多个线程共享一个静态变量就可以实现在线程间通讯,但是这需要注意的就是线程同步问题. 一.没考虑线程同步: package com.wyf; publi ...
- Java 线程间通讯
/* 线程间通讯: 多个线程在处理同一资源,但是任务却不同. */ package com.cwcec.test; class Input implements Runnable { Resource ...
- JMM之Java线程间通讯——等待通知机制及其经典范式
在并发编程中,实际处理涉及两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体). 通信是指线程之间以何种机制来交换信息.在共享内存的并发模型里,线程之间共享程序的公共状 ...
- java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...
- 黑马程序员——JAVA基础之多线程的线程间通讯等
------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...
- (转载)Java里快如闪电的线程间通讯
转自(http://www.infoq.com/cn/articles/High-Performance-Java-Inter-Thread-Communications) 这个故事源自一个很简单的想 ...
- Java中快如闪电的线程间通讯
这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...
- Java 里快如闪电的线程间通讯
这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...
- 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...
随机推荐
- SmartAdmin 打开速度慢的原因
最近在使用SmartAdmin做个小东西,发布在公网上,我的机器打开飞快,但是到了其它人的机器上变得极慢了.而且在我的手机上也打开变慢. 查找原因,原来如此. <link re ...
- 深入认识JavaScript 中的this指针
深入认识JavaScript 中的this指针this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象.在实现对象的方法时,可以使用this指针来获得该对象自身的引用.和传统意义的面向对象 ...
- linux系统下搭建php环境之-Discuz论坛
1.安装搭建论坛必要的软件 apache php mysql CentOS系统我们可以直接使用 yum install 的方式进行软件安装,腾讯云有提供软件安装源,是同步CentOS官方的安装源,包涵 ...
- RSA加密工具包
主要参考: http://www.blogjava.net/icewee/archive/2012/05/19/378570.html http://snowolf.iteye.com/ 基于以上代码 ...
- Slow HTTP Denial of Service Attack
整改建议 1.中断使用URL不支持HTTP方法访问的会话 2.限制HTTP头及包长至一个合理数值 3.设置一个绝对的会话超时时间 4.服务器支持backlog的情况下,需设置一个合理的大小 5.设置一 ...
- C#分析搜索引擎URL得到搜索关键字,并判断页面停留时间以及来源页面
前台代码: var start; var end; var state; var lasturl = document.referrer; start = new Date($.ajax({ asyn ...
- 【python】环境变量的配置
在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1.首先需要在系统中注册python环境变量:假设python的安装路径为c:\p ...
- (转)VS.NET2010水晶报表安装部署[VS2010]
本文转载自:http://www.cnblogs.com/xiaofengfeng/p/3325793.html 欢迎C#高手加盟QQ群:9340166 水晶报表VS2010版IDE安装标准版SAP ...
- SQLite加密的方法(c#)
http://blog.csdn.net/xjbx/article/details/2712236 设置下密码就可以了 http://bbs.csdn.net/topics/380018685 编译为 ...
- 黄聪:发送键盘指令System.Windows.Forms.SendKeys.Send
若要指定在按键(如 Enter 或 Tab)时不显示的字符,以及表示操作而不表示字符的键,请使用下表中的代码: 键 代码 Backspace {BACKSPACE}.{BS} 或 {BKSP} B ...