
前言
在并發(fā)編程中,需要處理兩個問題:線程之間如何通信及線程之間如何同步。通知是指線程之間以何種機制來交換信息。在命令式編程中,線程之間的通信機制有兩種:共享內(nèi)存和消息傳遞。
在共享內(nèi)存的并發(fā)模型里,線程之間共享程序的公共狀態(tài),通過寫-讀內(nèi)存中的公共狀態(tài)進行隱式通信。而子啊消息傳遞的并發(fā)模型里,線程之間沒有公共狀態(tài),線程之間必須通過發(fā)送消息來顯式進行通信。
Java 的并發(fā)才作用的是共享內(nèi)存模型,Java線程之間的通信總是隱式進行,整個通信過程對程序員完全透明。
而Java中還有另一種用的比較少的線程間的通信方式:管道流。
如何使用?
管道輸入/輸入流和普通的文件輸入/輸出流或者網(wǎng)絡(luò)輸入/輸出流不同之處在于,它主要用于線程之間的數(shù)據(jù)傳輸,而傳輸?shù)拿浇闉閮?nèi)存。
管道輸入/輸入流主要包括了如下4種具體實現(xiàn):PipedOutputStream,PipedInputStream,PipedReader 和 PipedWriter,前兩種面向字節(jié),而后兩種面向字符。
我們先來一個例子看看:
public class PipedStreamDemo {
public static void main(String[] args) throws IOException {
PipedWriter writer = new PipedWriter();
PipedReader reader = new PipedReader();
PipedInputStream inputStream = new PipedInputStream();
PipedOutputStream outputStream = new PipedOutputStream();
// 將輸出流和輸入流連接
writer.connect(reader);
Thread printThread = new Thread(new Print(reader));
printThread.start();
int receive;
try {
while ((receive = System.in.read()) != -1) {
// 從main線程寫到 print 線程
writer.write(receive);
}
} finally {
writer.close();
}
}
static class Print implements Runnable {
private PipedReader in;
public Print(PipedReader in) {
this.in = in;
}
@Override
public void run() {
int receive;
try {
while ((receive = in.read()) != -1) {
// 讀取 main 線程發(fā)送過來的數(shù)據(jù)并打印
System.out.print((char) receive);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
上面的代碼種,創(chuàng)建了 printThread,它用來接受 main 線程的輸入,任何 main 線程的輸入均通過 PipedWriter 寫入,而 printThread 在另一端通過 PipedReader 將內(nèi)容讀出并打印。
對于 Piped 類型的流,必須先要進行綁定,也就是調(diào)用 connect 方法,如果沒有將輸入 / 輸出流綁定起來,對于該流的訪問將會拋出異常。
而作為這兩個類連接的重要方法 connect 方法式如何實現(xiàn)的呢?
public synchronized void connect(PipedReader snk) throws IOException {
if (snk == null) {
throw new NullPointerException();
} else if (sink != null || snk.connected) {
throw new IOException("Already connected");
} else if (snk.closedByReader || closed) {
throw new IOException("Pipe closed");
}
sink = snk;
snk.in = -1;
snk.out = 0;
snk.connected = true;
}
首先參數(shù)判斷,然后將輸入流設(shè)置為輸出流的 sink 屬性。這樣就將兩個流關(guān)聯(lián)了起來。實現(xiàn)了兩個線程的通信。
總結(jié)
總的來說,該類的應(yīng)用場景并不是很多,只是我們應(yīng)該知道另一種線程通信的方式。嗯,就醬。
good luck ?。。。?/p>