摘要:不建議對這兩個對象嘗試使用單個線程,因為這樣可能會造成該線程死鎖。構造函數創建尚未連接到管道輸入流的管道輸出流。通常,數據由某個線程從對象讀取,并由其他線程將其寫入到相應的。
管道流
PipedOutputStream管道流的主要作用是可以進行兩個線程間的通訊,分為管道輸出流(PipedOutputStream)、管道輸入流(PipedInputStream),如果想要進行管道輸出,則必須要把輸出流連在輸入流之上,在PipedOutputStream類上有如下的一個方法用于連接管道:
public void connect(PipedInputStream snk)throws IOException通常是創建兩個多帶帶的線程來實現通信,如果是單個線程的話容易出現線程堵塞,因為輸出流最多只能向緩沖區寫入1024個字節的數據,如果超出就會出現線程堵塞,因此必須創建多個線程實現緩沖區的釋放和存儲
構造函數管道輸出流是管道的發送端,可以將管道輸出流連接到管道輸入流來創建一個通信管道,通常,數據由某個線程寫入 PipedOutputStream 對象,并由其他線程從連接的 PipedInputStream 讀取。不建議對這兩個對象嘗試使用單個線程,因為這樣可能會造成該線程死鎖。如果某個線程正從連接的管道輸入流中讀取數據字節,但該線程不再處于活動狀態,則該管道被視為處于 毀壞 狀態。
常用函數PipedOutputStream() 創建尚未連接到管道輸入流的管道輸出流。
PipedOutputStream(PipedInputStream snk) 創建連接到指定管道輸入流的管道輸出流。
PipedInputStreamclose() 關閉
void connect(PipedInputStream snk) 將此管道輸出流連接到接收者。
void flush() 刷新此輸出流并強制寫出所有緩沖的輸出字節。
void write(byte[] b, int off, int len) 將 len 字節從初始偏移量為 off 的指定 byte 數組寫入該管道輸出流。
void write(int b) 將指定 byte 寫入傳送的輸出流。
構造函數管道輸入流應該連接到管道輸出流;管道輸入流提供要寫入管道輸出流的所有數據字節。通常,數據由某個線程從 PipedInputStream 對象讀取,并由其他線程將其寫入到相應的 PipedOutputStream。不建議對這兩個對象嘗試使用單個線程,因為這樣可能死鎖線程。管道輸入流包含一個緩沖區,可在緩沖區限定的范圍內將讀操作和寫操作分離開。 如果向連接管道輸出流提供數據字節的線程不再存在,則認為該管道已損壞。
常用函數PipedInputStream() 創建尚未連接的 PipedInputStream。
PipedInputStream(PipedOutputStream src) 創建 PipedInputStream,使其連接到管道輸出流 src。
實例int available() 返回可以不受阻塞地從此輸入流中讀取的字節數。
void close() 關閉此管道輸入流并釋放與該流相關的所有系統資源。
void connect(PipedOutputStream src) 使此管道輸入流連接到管道輸出流 src。
int read() 讀取此管道輸入流中的下一個數據字節。
int read(byte[] b, int off, int len) 將最多 len 個數據字節從此管道輸入流讀入 byte 數組。
protected void receive(int b) 接收數據字節。
package IO; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; /** * Created by chenjiabing on 17-5-25. */ /** * 注意的問題: * 1.寫線程正在往緩沖區寫數據的時候,但是此時的讀線程的管道結束,那么此時的寫線程的管道就會發生IOException異常 * 2.讀線程正在從緩沖區讀數據的時候,但是此時的寫線程的管道已經結束了,此時就會引起讀線程的管道發生IOException異常 * 3.必須是啟用多線程才能實現管道之間的讀寫,否則會出現堵塞現象,因為這里的PipeOutputStream每次向緩沖區寫入的字節數最大是1024,如果不及時的減少緩沖區的數據量就會出現堵塞 */ public class demo7 { public static PipedOutputStream outputStream = new PipedOutputStream(); public static PipedInputStream inputStream = new PipedInputStream(); /** * 創建一個寫入數據進程,使用的是PipeOutStream,將數據寫入管道中 */ public static void send() { new Thread(new Runnable() { @Override public void run() { byte[] bytes = new byte[2000]; //創建一個2000字節的數組 while (true) { try { outputStream.write(bytes, 0, 2000); //寫入管道,但是這里的緩沖區最多寫入1024個字節的數據,因此這個是一次沒有寫完 System.out.println("寫入成功"); } catch (IOException e) { System.out.println("寫入失敗"); System.exit(1); } } } }).start(); } /** * 使用PipeInputStream創建一個讀取的線程 */ public static void receive() { new Thread(new Runnable() { @Override public void run() { byte[] bytes = new byte[100]; //一次性只讀取100個字節 int len = 0; try { len = inputStream.read(bytes, 0, 100); //讀取 while (len != -1) { System.out.println("已經讀取了" + len + "個字節"); len = inputStream.read(bytes, 0, 100); } } catch (IOException e) { System.out.println("讀取失敗"); System.exit(1); } } }).start(); } public static void main(String args[]) { try { inputStream.connect(outputStream); //連接 } catch (IOException e) { System.out.println("連接失敗"); System.exit(1); } send(); receive(); } }
問題注意:從上面的運行結果可以看出,緩沖區最多可以寫入1024個字節的數據,所以在緩沖區滿了之后上面的send進程就會堵塞等待緩沖區空閑,如果recieve進程不繼續讀取數據了,那么就會一直出現堵塞
解決方法寫線程正在往緩沖區寫數據的時候,但是此時的讀線程的結束讀取,那么此時的寫線程的管道就會發生IOException異常,可以將上面receive進程中的while(true)去掉就可以清楚的看出
讀線程正在從緩沖區讀數據的時候,但是此時的寫線程的管道已經結束了,此時就會引起讀線程的管道發生IOException異常,將上面的send進程中的while(true)去掉就可以實現這個問題
必須是啟用多線程才能實現管道之間的讀寫,否則會出現堵塞現象,因為這里的PipeOutputStream每次向緩沖區寫入的字節數最大是1024,如果不及時的減少緩沖區的數據量就會出現堵塞
參考文章后續更新中..........
http://www.cnblogs.com/lich/archive/2011/12/11/2283928.html
http://ifeve.com/java-io-%E7%AE%A1%E9%81%93/
http://www.cnblogs.com/chinareny2k/archive/2010/03/24/1693878.html
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67120.html
摘要:我的是忙碌的一年,從年初備戰實習春招,年三十都在死磕源碼,三月份經歷了阿里五次面試,四月順利收到實習。因為我心理很清楚,我的目標是阿里。所以在收到阿里之后的那晚,我重新規劃了接下來的學習計劃,將我的短期目標更新成拿下阿里轉正。 我的2017是忙碌的一年,從年初備戰實習春招,年三十都在死磕JDK源碼,三月份經歷了阿里五次面試,四月順利收到實習offer。然后五月懷著忐忑的心情開始了螞蟻金...
摘要:方法即為收集器,它接收高階函數和的后端掘金年的第一天,我坐在獨墅湖邊,寫下這篇文章。正因如此,所以最全系列教程后端掘金是從版本開始引入的一個新的,可以替代標準的。 設計模式之單例模式 - 掘金前言 作為一個好學習的程序開發者,應該會去學習優秀的開源框架,當然學習的過程中不免會去閱讀源碼,這也是一個優秀程序員的必備素養,在學習的過程中很多人會遇到的障礙,那就是設計模式。很多優秀的框架會運...
摘要:從通道進行數據寫入創建一個緩沖區,填充數據,并要求通道寫入數據。三之通道主要內容通道介紹通常來說中的所有都是從通道開始的。從中選擇選擇器維護注冊過的通道的集合,并且這種注冊關系都被封裝在當中停止選擇的方法方法和方法。 由于內容比較多,我下面放的一部分是我更新在我的微信公眾號上的鏈接,微信排版比較好看,更加利于閱讀。每一篇文章下面我都把文章的主要內容給列出來了,便于大家學習與回顧。 Ja...
摘要:簡介簡介也稱作套接字,是在應用層和傳輸層之間的一個抽象層,它把層復雜的操作抽象為幾個簡單的接口供應用層調用以實現進程在網絡中通信。它分為流式套接字和數據包套接字,分別對應網絡傳輸控制層的和協議。1.Socket簡介 Socket也稱作套接字,是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層復雜的操作抽象為幾個簡單的接口供應用層調用以實現進程在網絡中通信。它分為流式套接字和數據包套接字,...
閱讀 680·2021-09-30 09:47
閱讀 2873·2021-09-04 16:40
閱讀 857·2019-08-30 13:18
閱讀 3452·2019-08-29 16:22
閱讀 1555·2019-08-29 12:36
閱讀 586·2019-08-29 11:11
閱讀 1478·2019-08-26 13:47
閱讀 1132·2019-08-26 13:32