PipedInputStream和PipedOutputStream的使用例子_实例化 pipedoutputstream-程序员宅基地

技术标签: Java  string  byte  testing  thread  buffer  class  

通过学习PipedInputStream和PipedOutputStream代码,发现有两点值得我们学习:
1、notifyAll(), wait(1000);    先把对象上所有的等待线程唤醒,然后把自己睡去一定时间后醒来。 和我们平时写生产者消费者时wait(), notifyAll()有一点点不一样。
2、处理循环buffer的方式不一样,用in==-1来表示buffer为空,同时处理buffer时是常常一段一段读取(如write()里的nextTransferAmount)。
具体内容自己去读sun的源代码,详细对生产者和消费者写法会有新的认识。

下面我们给出两个对PipedInputStream和PipedOutputStream使用的例子来体会他们的用法:

package org.study.io;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipedStreamTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Producer p = new Producer();
		Consumer c = new Consumer();
		Thread t1 = new Thread(p);
		Thread t2 = new Thread(c);
		try {
			p.getPipedOutputStream().connect(c.getPipedInputStream());
			t2.start();
			t1.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static class Producer implements Runnable {
		private PipedOutputStream pos;

		public Producer() {
			pos = new PipedOutputStream();
		}

		public PipedOutputStream getPipedOutputStream() {
			return pos;
		}

		@Override
		public void run() {
			try {
				for (int i = 1; i <= 10; i++) {
					pos.write(("This is a testing message, messageId=" + i + "\n").getBytes());
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					pos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private static class Consumer implements Runnable {
		private PipedInputStream pis;

		public Consumer() {
			pis = new PipedInputStream();
		}

		public PipedInputStream getPipedInputStream() {
			return pis;
		}

		@Override
		public void run() {
			int len = -1;
			byte[] buffer = new byte[1024];
			try {
				//read(buffer, 0, buffer.length)函数作用有两个:
				//(1)若有buffer.length个数据可读,则返回buffer.length个数据;
				//   否则读取当前可读的所有数据,个数小于buffer.length;
				//(2)若没有数据可读,则让读进程等待(见read()函数)
				while ((len = pis.read(buffer)) != -1) {
					System.out.println(new String(buffer, 0, len));
				}
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				try {
					pis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

}


注: PipedInputStream和PipedOutStream适用于两个线程之间通信,不适合多个线程之间通信。因为PipedInputStream里的writeSide和readSide获得了对线程的引用,多个线程通信的话,这两个变量经常变化,引起PipedInputStream的函数不能正常工作,故不适合多个线程之间通信。

测试代码如下:

package org.study.io;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipedMultiThreadTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		PipedOutputStream pos = new PipedOutputStream();
		PipedInputStream pis = new PipedInputStream();
		try {
			pis.connect(pos);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Producer p = new Producer(pos);
		Consumer c = new Consumer(pis);
		
		Thread tp1 = new Thread(p, "生产者1号");
		Thread tp2 = new Thread(p, "生产者2号");
		Thread tp3 = new Thread(p, "生产者3号");
		Thread tp4 = new Thread(p, "生产者4号");
		Thread tp5 = new Thread(p, "生产者5号");
		
		Thread tc1 = new Thread(c, "消费者1号");
		Thread tc2 = new Thread(c, "消费者2号");
		Thread tc3 = new Thread(c, "消费者3号");
		Thread tc4 = new Thread(c, "消费者4号");
		Thread tc5 = new Thread(c, "消费者5号");
		
		tc1.start();
		tc2.start();
		tc3.start();
		tc4.start();
		tp1.start();
		tp2.start();
		tc5.start();
		tp3.start();
		tp4.start();
		tp5.start();
	}

	private static class Producer implements Runnable {
		private PipedOutputStream pos;

		public Producer(PipedOutputStream pos) {
			this.pos = pos;
		}

		@Override
		public void run() {
			try {
				for (int i = 1; i <= 10; i++) {
					pos.write(("threadName="+Thread.currentThread().getName()+", messageId=" + i + "\n").getBytes());
				}
			} catch (IOException e) {
				e.printStackTrace();
			} 
		}
	}

	private static class Consumer implements Runnable {
		private PipedInputStream pis;

		public Consumer(PipedInputStream pis) {
			this.pis = pis;
		}
		
		@Override
		public void run() {
			int len = -1;
			byte[] buffer = new byte[1024];
			try {
				//read(buffer, 0, buffer.length)函数作用有两个:
				//(1)若有buffer.length个数据可读,则返回buffer.length个数据;
				//   否则读取当前可读的所有数据,个数小于buffer.length;
				//(2)若没有数据可读,则让读进程等待(见read()函数)
				while ((len = pis.read(buffer)) != -1) {
					System.out.println(new String(buffer, 0, len));
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/walkerJong/article/details/7025223

智能推荐

token与cookie区别_token和cookie的区别-程序员宅基地

文章浏览阅读1.2k次。总而言之,Token 和 Cookie 在身份验证和授权方面都有其特定的用途和优势。选择使用哪种机制取决于具体的应用场景和安全需求。_token和cookie的区别

微信公众号一、接入微信并实现机器人自动回复功能_glm 微信云托管 公众号 微信机器人-程序员宅基地

文章浏览阅读2.6k次。一、说明微信公众平台https://mp.weixin.qq.com/cgi-bin/loginpage?t=wxm2-login&lang=zh_CN测试平台https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login本文demo链接:https://pan.baidu.com/s/1syGGvdCJqcSPnZ..._glm 微信云托管 公众号 微信机器人

PTA 6-4 重写父类方法equals (5分)-程序员宅基地

文章浏览阅读6.4k次,点赞2次,收藏11次。6-4 重写父类方法equals (5分)在类Student中重写Object类的equals方法。使Student对象学号(id)相同时判定为同一对象。函数接口定义:在类Student中重写Object类的equals方法。使Student对象学号(id)相同时判定为同一对象。裁判测试程序样例:class Student { int id; String name; i..._6-4 重写父类方法equals

GridView的PagerTemplate分页-程序员宅基地

文章浏览阅读55次。Code<asp:GridViewID="gvProject"runat="server"BorderColor="Gray"Height="20px"Width="98%"AllowPaging="True"AutoGenerateColumns="False"EmptyDataText="没有符合查询条件的数据!"OnDataBound="gvProject..._ystem.web.ui.webcontrols.templatefield”不具有名为“pagertemplate”的公共属

SpringMVC篇-程序员宅基地

文章浏览阅读131次。SpringMVC目录1 什么是SpringMVC1.1 概述1.2 中心控制器1.3 SpringMVC执行原理2 创建MVC程序2.1 配置方式2.2 注解方式1 什么是SpringMVC1.1 概述Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。官方文档:https://docs.spring.io/spring-framework/docs/5.3.x-SNAPSHOT/reference/html/web.html#spring-

Android应用生成测试覆盖率报告_android mk testcoverageenabled-程序员宅基地

文章浏览阅读774次。对于使用AndroidJUnit4 runner创建的Android集成测试用例,之前一直都没有发现,一种合适的产生代码覆盖率的方式。我曾经尝试过很多方式,但是要不就是不奏效,要不就是只合适我现在已经不再使用的Robolectric测试框架,其他开发者,也渐渐不再新项目中使用这个测试框架了。比如Square的Sqlbrite项目,现在已经开始采用AndroidJUnit4 runner进行他们的项..._android mk testcoverageenabled

随便推点

“Unknown initial character set index '255' received from serve”错误解决过程 - Mybatis 示例_unknown initial character 255-程序员宅基地

文章浏览阅读4.7k次,点赞8次,收藏13次。今天在学习Mybaits的时候,根据教程写出了一个第一个程序——从数据库读取一条数据并打印。当一切都就绪了:user.javaUserMapper.xmlmybatis-config.xml测试类依葫芦画瓢地写下来,以为没问题了,运行这个测试方法,竟然报错了:org.apache.ibatis.exceptions.PersistenceException: ### Err..._unknown initial character 255

[附源码]JAVA+ssm校友信息管理系统(程序+Lw)_java校友信息管理系统-程序员宅基地

文章浏览阅读307次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:SSM + mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;_java校友信息管理系统

linux网络编程之socket编程(三)-程序员宅基地

文章浏览阅读94次。今天继续对socket编程进行学习,在学习之前,需要回顾一下上一篇中编写的回射客户/服务器程序(http://www.cnblogs.com/webor2006/p/3923254.html),因为今天的知识点需要基于它来进行说明,下面来回顾一下关键代码:对于服务器端:echosrv.c对于客户端:echocli.c下面通过一个简单的图来描述一下其关系:可想而知,这两个套接字都有..._if (connect(sock, (struct sockaddr*)(&addr), sizeof(addr))

magic4.0跟harmonyos,支持升级Harmony 2.0 Magic UI 4.0 9月中旬招募公测-程序员宅基地

文章浏览阅读1.4k次。Magic UI 4.0系统将于9月中旬开始招募公测,适配荣耀30系列以及荣耀V30系列产品,后续同样支持升级为HarmonyOS 2.0系统。【PChome手机频道资讯报道】9月10日,华为开发者大会(HDC 2020)正式召开,正式推出HarmonyOS 2.0与EMUI 11操作系统。与此同时,荣耀在微博官宣,Magic UI 4.0系统也将于9月中旬开始招募公测,Magic UI 4.0广..._magicui4什么时候升的

关于启动报错:Field xxxMapper in com.xxx.service.impl.xxxServiceImpl required a bean of type的解决方案_field teachermapper in com.example.itextdemo.servi-程序员宅基地

文章浏览阅读3w次,点赞14次,收藏8次。检测你的启动类Application的MapperScan注解扫描是否配置正确!_field teachermapper in com.example.itextdemo.service.impl.eduteacherservicei

win7成功下编译VLC1.0.5-程序员宅基地

文章浏览阅读64次。想用最新版本的VLC 于是编译1.0.5版本由于有了前面的基础只需要以下几步就OK:关于修改1. 很多人提示的修改libtool第144行。--我的144行不是blank ,so没有更改;22) 注释掉Makefile.am第697,727,738行,就是行首加入#。#cp "$(top_srcdir)/extras..._vlc-1.0.5-win32.exe

推荐文章

热门文章

相关标签