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

發佈了52 篇原創文章 · 獲贊 178 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章