請大家尊重勞動成果,轉載請註明出處: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