java多線程編程之管道通信詳解
上一章節(jié)講了wait/notify通信,這一節(jié)我們來(lái)探討使用管道進(jìn)行通信。
java中提供了IO流使我們很方便的對(duì)數(shù)據(jù)進(jìn)行操作,pipeStream是一種特殊的流,用于不同線程間直接傳送數(shù)據(jù)。一個(gè)線程將數(shù)據(jù)發(fā)送到輸出管道,另一個(gè)線程從輸入管道讀取數(shù)據(jù)。通過(guò)管道實(shí)現(xiàn)通信不需要借助臨時(shí)文件這類東西。
java中提供了四個(gè)類使得線程間可以通信:
①字節(jié)流:PipeInputStream,PipedOutputStream
②字符流:PipedReader,PipedWriter
下面我們看看字節(jié)流的實(shí)現(xiàn)方法:
package pipeInputOutput; //輸出流 import java.io.IOException; import java.io.PipedOutputStream; public class WriteDate { public void writeMethod(PipedOutputStream out) { try { System.out.println("write:"); for(int i=0;i<300;i++) { String outDate=""+(i+1); out.write(outDate.getBytes()); System.out.print(outDate); } System.out.println(); out.close(); }catch(IOException e) { e.printStackTrace(); } } }
package pipeInputOutput; //輸入流 import java.io.IOException; import java.io.PipedInputStream; public class ReadDate { public void ReadDate(PipedInputStream input) { try { System.out.println("read:"); byte[] byteArray=new byte[20]; int readLength=input.read(byteArray); while(readLength!=-1) { String newDate=new String(byteArray,0,readLength); System.out.print(newDate); readLength=input.read(byteArray); } System.out.println(); input.close(); }catch(IOException e){ e.printStackTrace(); } } }
package pipeInputOutput; import java.io.PipedOutputStream; //輸出線程 public class ThreadWrite extends Thread { private WriteDate write; private PipedOutputStream out; public ThreadWrite(WriteDate write,PipedOutputStream out) { super(); this.write=write; this.out=out; } public void run() { write.writeMethod(out); } }
package pipeInputOutput; import java.io.PipedInputStream; //輸入線程 public class ThreadRead extends Thread{ private ReadDate read; private PipedInputStream in; public ThreadRead(ReadDate read,PipedInputStream in) { super(); this.read=read; this.in=in; } public void run() { read.ReadDate(in); } }
package pipeInputOutput; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; //測(cè)試方法 public class Run { public static void main(String[] args) { try { WriteDate write=new WriteDate(); ReadDate read=new ReadDate(); PipedInputStream inputStream=new PipedInputStream(); PipedOutputStream outputStream=new PipedOutputStream(); //輸出流與輸入流進(jìn)行連接。 outputStream.connect(inputStream); //inputStream.connect(outputStream); ThreadRead readThread=new ThreadRead(read,inputStream); readThread.start();//先啟動(dòng)輸出線程 Thread.sleep(2000); ThreadWrite writeThread=new ThreadWrite(write,outputStream); writeThread.start();//后啟動(dòng)輸入線程 } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }
控制臺(tái)輸出:
read:
write:
123456789101112131415161718192021...
123456789101112131415161718192021...
上面測(cè)試中,先啟動(dòng)輸入線程,然后因?yàn)闆](méi)有線程被寫入所以線程被阻塞,知道有數(shù)據(jù)寫入。
我們接著繼續(xù)看看字符流的實(shí)現(xiàn)方法:
package pipeInputOutput1; import java.io.IOException; import java.io.PipedWriter; //字符輸出流 public class WriteDate { public void writeMethod(PipedWriter out) { try { System.out.println("write:"); for(int i=0;i<300;i++) { String outDate=""+(i+1); out.write(outDate); System.out.print(outDate); } System.out.println(); out.close(); }catch(IOException e) { e.printStackTrace(); } } }
package pipeInputOutput1; import java.io.IOException; import java.io.PipedReader; //字符輸入流 public class ReadDate { public void readMethod(PipedReader in) { try { System.out.println("read:"); char[] byteArray=new char[20]; int readLength=in.read(byteArray); while(readLength!=-1) { String newDate=new String(byteArray,0,readLength); System.out.print(newDate); readLength=in.read(byteArray); } System.out.println(); in.close(); } catch (IOException e) { e.printStackTrace(); } } }
package pipeInputOutput1; import java.io.PipedWriter; //輸出流線程 public class WriteThread extends Thread { private WriteDate write; private PipedWriter out; public WriteThread(WriteDate write,PipedWriter out) { super(); this.write=write; this.out=out; } public void run() { write.writeMethod(out); } }
package pipeInputOutput1; import java.io.PipedReader; //輸入流線程 public class ReadThread extends Thread{ private ReadDate read; private PipedReader in; public ReadThread(ReadDate read,PipedReader in) { super(); this.read=read; this.in=in; } public void run() { read.readMethod(in); } }
package pipeInputOutput1; import java.io.IOException; import java.io.PipedReader; import java.io.PipedWriter; //測(cè)試方法 public class run { public static void main(String[] args) { try { WriteDate write=new WriteDate(); ReadDate read=new ReadDate(); PipedWriter out=new PipedWriter(); PipedReader in=new PipedReader(); //連接輸出流與輸入流 out.connect(in); //in.connect(out); ReadThread threadread=new ReadThread(read,in); threadread.start(); Thread.sleep(2000); WriteThread threadwrite=new WriteThread(write,out); threadwrite.start(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }
字符流額字節(jié)流大同小異,上面的例子中字符流不需要?jiǎng)?chuàng)建字節(jié)數(shù)組而已。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring 4.0新功能:@Conditional注解詳細(xì)介紹
Spring Boot的強(qiáng)大之處在于使用了Spring 4框架的新特性:@Conditional注釋,此注釋使得只有在特定條件滿足時(shí)才啟用一些配置。下面這篇文章主要給大家介紹了關(guān)于Spring4.0中新功能:@Conditional注解的相關(guān)資料,需要的朋友可以參考下。2017-09-09Springboot如何集成jodconverter做文檔轉(zhuǎn)換
這篇文章主要介紹了Springboot如何集成jodconverter做文檔轉(zhuǎn)換問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08mybatis-plus使用generator實(shí)現(xiàn)逆向工程
mybatis-plus-generator在3.5.0以及以后的版本使用新的方式逆向生成代碼,本文主要介紹了mybatis-plus使用generator實(shí)現(xiàn)逆向工程,具有一定的參考價(jià)值,感興趣的可以了解一下2022-05-05Java中JDBC事務(wù)與JTA分布式事務(wù)總結(jié)與區(qū)別
Java事務(wù)的類型有三種:JDBC事務(wù)、JTA(Java Transaction API)事務(wù)、容器事務(wù),本文詳細(xì)介紹了JDBC事務(wù)與JTA分布式事務(wù),有需要的可以了解一下。2016-11-11SpringBoot @value注解動(dòng)態(tài)刷新問(wèn)題小結(jié)
@Value注解 所對(duì)應(yīng)的數(shù)據(jù)源來(lái)自項(xiàng)目的 Environment 中,我們可以將數(shù)據(jù)庫(kù)或其他文件中的數(shù)據(jù),加載到項(xiàng)目的 Environment 中,然后 @Value注解 就可以動(dòng)態(tài)獲取到配置信息了,這篇文章主要介紹了SpringBoot @value注解動(dòng)態(tài)刷新,需要的朋友可以參考下2023-09-09Java定時(shí)清理過(guò)期文件的實(shí)例代碼
這篇文章主要介紹了Java定時(shí)清理過(guò)期文件的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-12-12Java使用Tinify實(shí)現(xiàn)圖片無(wú)損壓縮(4M無(wú)損壓縮到1M)的方法
在當(dāng)今的數(shù)字化時(shí)代,圖片已成為網(wǎng)站、應(yīng)用和社交媒體中不可或缺的元素,然而,大尺寸的圖片不僅會(huì)增加頁(yè)面或者客戶端加載時(shí)間,還會(huì)占用大量的存儲(chǔ)空間,本文將詳細(xì)介紹如何利用Tinify壓縮圖片,并將其上傳至OSS,重點(diǎn)介紹圖片壓縮實(shí)現(xiàn)方式,需要的朋友可以參考下2024-08-08如何在Spring Boot啟動(dòng)時(shí)運(yùn)行定制的代碼
在本文中您將學(xué)習(xí)如何掛鉤應(yīng)用程序引導(dǎo)程序生命周期并在Spring Boot啟動(dòng)時(shí)執(zhí)行代碼。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-122023最新版本idea用maven新建web項(xiàng)目(親測(cè)不報(bào)錯(cuò))
這篇文章主要給大家介紹了關(guān)于2023最新版本idea用maven新建web項(xiàng)目,Maven是當(dāng)今Java開(kāi)發(fā)中主流的依賴管理工具,文中介紹的步驟親測(cè)不報(bào)錯(cuò),需要的朋友可以參考下2023-07-07