Thread詳解10:用管道進行線程間通信

1 字節流管道

通常,數據由某個線程從 PipedInputStream 對象讀取,並由其他線程將其寫入到相應的 PipedOutputStream。不建議對這兩個對象嘗試使用單個線程,因爲這樣可能死鎖線程。管道輸入流包含一個緩衝區,可在緩衝區限定的範圍內將讀操作和寫操作分離開。 如果向連接管道輸出流提供數據字節的線程不再存在,則認爲該管道已損壞。

1.1 PipedInputStream

這裏寫圖片描述


1.2 PipedOutputStream

這裏寫圖片描述


1.3 使用字節流管道進行線程間的通信

WriteData.java

package pipe;

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

public class WriteData extends Thread {
    private PipedOutputStream pipedOS;
    private String data;

    public WriteData(PipedOutputStream pipedOS, String data) {
        super("Writer");
        this.pipedOS = pipedOS;
        this.data = data;
    }

    @Override
    public void run() {
        super.run();
        try {
            String tmp;
            for (int i = 0; i < 6; i++) {
                tmp = data + i + " ";
                System.out.println(Thread.currentThread().getName() + " writed " + tmp + " into the pipe.");
                pipedOS.write(tmp.getBytes());
            }
            pipedOS.flush();
            pipedOS.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

ReadData.java

package pipe;

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

public class ReadData extends Thread {
    private PipedInputStream pipedIS;

    public ReadData(PipedInputStream pipedIS) {
        super("Reader");
        this.pipedIS = pipedIS;
    }

    @Override
    public void run() {
        super.run();
        try {
            System.out.println(Thread.currentThread().getName() + " begined reading the data from the pipe.");
            byte[] bytes = new byte[20];
            int readLen = -1;
            readLen = pipedIS.read(bytes);
            while (readLen != -1) {
                String s = new String(bytes, 0, readLen);
                System.out.println(s);
                try {
                    readLen = pipedIS.read(bytes);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println();
            pipedIS.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        PipedInputStream pipedInputStream = new PipedInputStream();
        PipedOutputStream pipedOutputStream = new PipedOutputStream();
        try {
            pipedInputStream.connect(pipedOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        WriteData writeData = new WriteData(pipedOutputStream, "ABC");
        ReadData readData = new ReadData(pipedInputStream);

        writeData.start();
        readData.start();
    }

}

輸出

Reader begined reading the data from the pipe.
Writer writed ABC0  into the pipe.
Writer writed ABC1  into the pipe.
Writer writed ABC2  into the pipe.
Writer writed ABC3  into the pipe.
Writer writed ABC4  into the pipe.
Writer writed ABC5  into the pipe.
ABC0 ABC1 ABC2 ABC3 
ABC4 ABC5 


2 字符流通道

2.1 PipedReader

這裏寫圖片描述


2.2 PipedWriter

這裏寫圖片描述

由於管道通信的原理是一樣的,不過一個是處理字節流,一個是處理字符流,區別不大,所以這裏代碼就不再編寫了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章