Java 多线程通信之管道通信(pipe)及常见异常处理

    请大家尊重劳动成果,转载请注明出处:http://blog.csdn.net/caoshichao520326/article/details/8995583

    Java多线程之间要交换信息,有时只能用管道来完成,在使用管道通信时,经常会碰到“java - IOException: Read end dead”或者“java - IOException: Write end dead”的异常,下面针对这个问题作出一个简单的分析,首先是写了一个管道通信的demo供大家参考。程序如下:

package com.csc.pipetest;

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

/**
 * 管道通信demo
 * 
 * @author csc
 * 
 */
public class PipeTest {

	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 PipeTest().new Producer(pos);
		// 创建消费者线程
		Consumer c = new Consumer(pis);
		// 启动线程
		p.start();
		c.start();
	}

	// 生产者线程(与一个管道输入流相关联)
	private class Producer extends Thread {
		private PipedOutputStream pos;

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

		public void run() {
			int i = 8;
			// while (true) {//加入此句将出现“java - IOException: Read end dead”异常
			try {
				pos.write(i);
			} catch (IOException e) {
				e.printStackTrace();
			}
			// }

		}
	}

	// 消费者线程(与一个管道输入流相关联)
	private static class Consumer extends Thread {
		private PipedInputStream pis;

		public Consumer(PipedInputStream pis) {
			this.pis = pis;
		}

		public void run() {
			// while(true){//加入此句将出现“java - IOException: Write end dead”异常
			try {
				System.out.println(pis.read());
			} catch (IOException e) {
				e.printStackTrace();
			}
			// }

		}
	}
}

    上面的程序是可以正确运行的,①若将第46行和第52行注释掉的代码加上,将会抛出“java - IOException: Read end dead”。②若将第66行和第72行注释掉的代码加上,将会抛出“java - IOException: Write end dead”。原因都是一样的:在利用管道读写数据时,必须保证利用管道读写数据的线程都不能退出。针对上面的程序,如果是第①种情况,是因为Consumer(消费者)线程在读出管道中的数据后,线程就运行结束退出了。这时再向建立链接管道的线程Producer中写入数据时就会抛出异常。同样,如果是第②种情况就,是因为Producer(生产者)线程在写入管道中的数据后,线程就运行结束退出了。这时再由建立链接管道的线程Consumer中读出数据时就会抛出异常。

    细心的读者会发现,程序的第37行和第58行在创建内部类是一个使用了“static”关键字,一个没有使用,这决定了程序的第28行和第30行在使实例化对象时的方式不同,这是创建内部类要求的否则会出现编译错误,详细分析见:http://blog.csdn.net/caoshichao520326/article/details/8961297

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值