java io學習(三) 管道的簡介,源碼分析和樣本

來源:互聯網
上載者:User

管道(PipedOutputStream和PipedInputStream)的簡介,源碼分析和樣本

本章,我們對java 管道進行學習。

java 管道介紹

在java中,PipedOutputStream和PipedInputStream分別是管道輸出資料流和管道輸入資料流。

它們的作用是讓多線程可以通過管道進行線程間的通訊。在使用管道通訊時,必須將PipedOutputStream和PipedInputStream配套使用。

使用管道通訊時,大致的流程是:我們線上程A中向PipedOutputStream中寫入資料,這些資料會自動的發送到與PipedOutputStream對應的PipedInputStream中,進而儲存在PipedInputStream的緩衝中;此時,線程B通過讀取PipedInputStream中的資料。就可以實現,線程A和線程B的通訊。

PipedOutputStream和PipedInputStream源碼分析

下面介紹PipedOutputStream和PipedInputStream的源碼。在閱讀它們的源碼之前,建議先看看源碼後面的樣本。待理解管道的作用和用法之後,再看源碼,可能更容易理解。

此外,由於在“java io系列03之 ByteArrayOutputStream的簡介,源碼分析和樣本(包括OutputStream)”中已經對PipedOutputStream的父類OutputStream進行了介紹,這裡就不再介紹OutputStream。

在“java io系列02之 ByteArrayInputStream的簡介,源碼分析和樣本(包括InputStream)”中已經對PipedInputStream的父類InputStream進行了介紹,這裡也不再介紹InputStream。

1. PipedOutputStream 源碼分析(基於jdk1.7.40)

package java.io;     import java.io.*;     public class PipedOutputStream extends OutputStream {         // 與PipedOutputStream通訊的PipedInputStream對象    private PipedInputStream sink;         // 建構函式,指定配對的PipedInputStream    public PipedOutputStream(PipedInputStream snk)  throws IOException {        connect(snk);    }         // 建構函式    public PipedOutputStream() {    }         // 將“管道輸出資料流” 和 “管道輸入資料流”串連。    public synchronized void connect(PipedInputStream snk) throws IOException {        if (snk == null) {            throw new NullPointerException();        } else if (sink != null || snk.connected) {            throw new IOException("Already connected");        }        // 設定“管道輸入資料流”        sink = snk;        // 初始化“管道輸入資料流”的讀寫位置        // int是PipedInputStream中定義的,代表“管道輸入資料流”的讀寫位置        snk.in = -1;        // 初始化“管道輸出資料流”的讀寫位置。        // out是PipedInputStream中定義的,代表“管道輸出資料流”的讀寫位置        snk.out = 0;        // 設定“管道輸入資料流”和“管道輸出資料流”為已串連狀態        // connected是PipedInputStream中定義的,用於表示“管道輸入資料流與管道輸出資料流”是否已經串連        snk.connected = true;    }         // 將int類型b寫入“管道輸出資料流”中。    // 將b寫入“管道輸出資料流”之後,它會將b傳輸給“管道輸入資料流”    public void write(int b)  throws IOException {        if (sink == null) {            throw new IOException("Pipe not connected");        }        sink.receive(b);    }         // 將位元組數組b寫入“管道輸出資料流”中。    // 將數組b寫入“管道輸出資料流”之後,它會將其傳輸給“管道輸入資料流”    public void write(byte b[], int off, int len) throws IOException {        if (sink == null) {            throw new IOException("Pipe not connected");        } else if (b == null) {            throw new NullPointerException();        } else if ((off < 0) || (off > b.length) || (len < 0) ||                   ((off + len) > b.length) || ((off + len) < 0)) {            throw new IndexOutOfBoundsException();        } else if (len == 0) {            return;        }        // “管道輸入資料流”接收資料        sink.receive(b, off, len);    }         // 清空“管道輸出資料流”。    // 這裡會調用“管道輸入資料流”的notifyAll();    // 目的是讓“管道輸入資料流”放棄對當前資源的佔有,讓其它的等待線程(等待讀取管道輸出資料流的線程)讀取“管道輸出資料流”的值。    public synchronized void flush() throws IOException {        if (sink != null) {            synchronized (sink) {                sink.notifyAll();            }        }    }         // 關閉“管道輸出資料流”。    // 關閉之後,會調用receivedLast()通知“管道輸入資料流”它已經關閉。    public void close()  throws IOException {        if (sink != null) {            sink.receivedLast();        }    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.