PipedInputStream和PipedOutputStream的使用例子

通过学习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();
			}
		}

	}

}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值