Java中利用管道實現執行緒間的通訊(轉)
Java中利用管道實現執行緒間的通訊(轉)[@more@]在java 語言中,提供了各種各樣的輸入輸出流(stream),使我們能夠很方便的對資料進行操作,其中,管道(pipe)流是一種特殊的流,用於在不同執行緒(threads)間直接傳送資料。一個執行緒傳送資料到輸出管道,另一個執行緒從輸入管道中讀資料。透過使用管道,實現不同執行緒間的通訊。無需求助於類似臨時檔案之類的東西。本文在簡要介紹管道的基本概念後,將以一個具體的例項pipeapp加以詳細說明。
1. 管道的建立與使用
java提供了兩個特殊的專門的類專門用於處理管道,它們就是pipedinputstream類和pipeoutputstream類。
Pipedinputstream代表了資料在管道中的輸出端,也就是執行緒向管道讀資料的一端;pipeoutputstream代表了資料在管道中的輸入端,也就是執行緒向管道寫資料的一端,這兩個類一起使用可以提供資料的管道流。
為了建立一個管道流,我們必須首先建立一個pipeoutstream物件,然後,建立pipeinputstream物件,例項如下:
pipeout= new pipedyoutstream();
pipein= new pipedputsteam(pipepout);
一旦建立了一個管道後,就可以象操作檔案一樣對管道進行資料的讀寫。
2. 演示程式: pipeapp
應用程式由三個程式組成:主執行緒(pipeapp.java)及由主執行緒啟動的兩個二級執行緒(ythread.java和 zthread.java),它們使用管道來處理資料。程式從一個內容為一行一行"x"字母的"input.txt"檔案中讀取資料,使用管道傳輸資料,第一次是利用執行緒ythread將資料"x"轉換為"y",最後利用執行緒zthread將"y"轉換為"z",之後,程式在螢幕上顯示修改後的資料。
主執行緒 (pipeapp.java)
在main()方法中,程式首先建立一個應用物件:pipeapp pipeapp=new pipeapp();
由於程式中流操作都需要使用IOException異常處理,所以設定了一個try塊。在try中,為了從原始檔中讀取資料,程式為"input.txt"檔案建立了一個輸入流Xfileln,:
fileinputstream xfileln= new fileinputstream("input.txt");
新的輸入流傳遞給changetoy()方法,讓執行緒ythread能讀取該檔案:
inputstream ylnpipe =pipeapp.changetoy(xfileln);
changetoy()方法建立將輸入資料"x"改變到"y"的執行緒ythread,並返回該執行緒的輸入管道:
inputstream zlnpipe = pipeapp.changetoz(ylnpipe);
changetoz()方法啟動將資料從"y"改變到"z"的執行緒zehread,主程式將使用從changetoz()返回的輸入管道。得到以修改的資料。
然後,程式將管道輸入流定位到datainputstream物件,使程式能夠使用readline()方法讀取資料:
datainputstream inputstream = new datainputstream(zlnpiepe);
建立了輸入流以後,程式就可以以行一行的讀取資料病顯示在螢幕上。
String str= inputstream.readline();
While(str!=null)
{
system.out.println(str);
str=inputstream.readline();
}
顯示完成之後,程式關閉輸入流:
inputstream.close();
changetoy()方法
changetoy()方法首先透過傳遞一個引數inputstream給datainputstream物件來定位資源的輸入流,使程式能使用readline()方法從流中讀取資料:
datainputstream xfileln =new datainutstream(inputstream);
然後,changetoy()建立輸出管道和輸入管道:
pipeoutstream pipeout = new pipeoutputstream();
pipeinputstream pipeln = new pipedinputsteam(pipeout);
為了能夠使用println()方法輸出修改的後的文字行到管道,程式將輸出管道定位到printstream物件:
printstream printstream = new printstream(pipeout);
現在,程式可以建立將資料從x改變到y的執行緒,該執行緒是ythread類的一個物件,他傳遞兩個引數:輸入檔案(xfileln)和輸出管道(呼叫printstream)
ythread ythread =new thread(xfileln,printstream);
之後,程式啟動執行緒:
changetoz()方法
changetoz()方法與changetoy()方法很相似,他從changetoy()返回的輸入流開始:
datainputstream yfileln= new datainputstream(inputstream);
程式建立一個新的管道:
pipedoutstream pipeout2 = new pipedoutputstream();
pipedinputstream pipeln2 = new pipedinputsream(pipeout2);
該執行緒透過這個新的管道發出修改後的資料(輸入流pipeln2)給主程式。
源程式如下:
//
//pipeapp.java-pipeapp的主應用程式
//
import java.io.*
class pipeapp
{
public static void main(string[] args)
{
pipeapp pipeapp=new pipeapp();
try
{
fileinputstream xfile =new fileinputstream("input.txt");
inputstream ylnpipe = pipeapp.changetoy(xfileln);
inputstream zlnpipe=pipeapp.changetoz(ylnpipe);
system.out.println();
system.out.println("here are the results");
system.out.pringln();
datainputstream inputstream = nes datainputstream(zlnpipe);
string str = inputstream.readline();
while (str!=null)
{
system.out.println(str);
str=inputstream.readline();
}
inputstream.close();
}
catch(exception e)
{
system.out.println(e.tostring());
}
}
public inputstream changetoy(inputstream inputstream)
{
try
{
datainputstream pipeout = new datainputsteam(inputstream);
pipedoutstream pipeout = new pipedoutputstream();
pipedlnsteam pipeln = new pipedlnputstream(pipeout);
printstream printstream = new printstream(pipeout);
ythread ythread = new ythread(xfileln,printstream);
ythread.start();
return pipeln;
}
catch(exeption e)
{
system.out.println(x.tostring());
}
return null;
}
public inputstream changetoz(inputstream inputsteam)
{
try
{
datainputstream yfileln = new datainputstream(inputstream);
pipeoutputstream pipeln2 = new pipedinputstream(pipeout2);
printrstream printstream2 = new printsteam(pipeout2);
zthread zthread = new zthread(yfileln,printstream2);
zthread.start();
return pipeln2;
}
catch(exception e)
{
system.out.println(e.tostring());
}
return null;
}
}
Ythread類和Zthread類
由於ythread類與zthread類基本一樣,在此僅以ythread為例加以說明。
Ythread的構造器接收兩個引數:輸入的檔案和第一個管道的輸出端,構造器儲存這兩個引數作為類的資料成員:
Ythread(datainputstream xfileln,pringstream printstream)
{
this.xfileln = xfileln;
this.printstream = printstream;
}
執行緒透過run()方法來處理資料。首先讀取一行資料,確保xstring不為空的情況下迴圈執行:
string xstring = xfileln.readline();
每讀一行資料,完成一次轉換
string ystring = xstring.replace(´x´,´y´);
然後將修改後的資料輸出到管道的輸出端:
prinstream.prinrln(ystring);
為了確保所有緩衝區的資料完全進入管道的輸出端:
pringstram.flush();
迴圈完成後,執行緒關閉管道輸出流:
pringstram.close();
ythread類的源程式如下:
//
//ythread.java
//
import java.io.*;
class ythread exteads thread
{
datainputstream xfileln;
pringstream printstream;
ythread(datainputstream xfileln,pringstream.printstream)
{
this.xfileln = xfileln;
this.printstream = printstream;
}
public void run()
{
try
{
string xstring = xfileln.readline();
while(xstring!=null)
{
string ystring= xstring.replace(´x´,´y´);
printstream.pringln(ystring);
printstream.flush();
xstring= xfileln.readline();
}
printstream.close();
}
catch{ioexception e}
{
system.out.println(e.tostring());
}
}
}
pipeapp應用程式使用microsoft visual j++1.1編譯
1. 管道的建立與使用
java提供了兩個特殊的專門的類專門用於處理管道,它們就是pipedinputstream類和pipeoutputstream類。
Pipedinputstream代表了資料在管道中的輸出端,也就是執行緒向管道讀資料的一端;pipeoutputstream代表了資料在管道中的輸入端,也就是執行緒向管道寫資料的一端,這兩個類一起使用可以提供資料的管道流。
為了建立一個管道流,我們必須首先建立一個pipeoutstream物件,然後,建立pipeinputstream物件,例項如下:
pipeout= new pipedyoutstream();
pipein= new pipedputsteam(pipepout);
一旦建立了一個管道後,就可以象操作檔案一樣對管道進行資料的讀寫。
2. 演示程式: pipeapp
應用程式由三個程式組成:主執行緒(pipeapp.java)及由主執行緒啟動的兩個二級執行緒(ythread.java和 zthread.java),它們使用管道來處理資料。程式從一個內容為一行一行"x"字母的"input.txt"檔案中讀取資料,使用管道傳輸資料,第一次是利用執行緒ythread將資料"x"轉換為"y",最後利用執行緒zthread將"y"轉換為"z",之後,程式在螢幕上顯示修改後的資料。
主執行緒 (pipeapp.java)
在main()方法中,程式首先建立一個應用物件:pipeapp pipeapp=new pipeapp();
由於程式中流操作都需要使用IOException異常處理,所以設定了一個try塊。在try中,為了從原始檔中讀取資料,程式為"input.txt"檔案建立了一個輸入流Xfileln,:
fileinputstream xfileln= new fileinputstream("input.txt");
新的輸入流傳遞給changetoy()方法,讓執行緒ythread能讀取該檔案:
inputstream ylnpipe =pipeapp.changetoy(xfileln);
changetoy()方法建立將輸入資料"x"改變到"y"的執行緒ythread,並返回該執行緒的輸入管道:
inputstream zlnpipe = pipeapp.changetoz(ylnpipe);
changetoz()方法啟動將資料從"y"改變到"z"的執行緒zehread,主程式將使用從changetoz()返回的輸入管道。得到以修改的資料。
然後,程式將管道輸入流定位到datainputstream物件,使程式能夠使用readline()方法讀取資料:
datainputstream inputstream = new datainputstream(zlnpiepe);
建立了輸入流以後,程式就可以以行一行的讀取資料病顯示在螢幕上。
String str= inputstream.readline();
While(str!=null)
{
system.out.println(str);
str=inputstream.readline();
}
顯示完成之後,程式關閉輸入流:
inputstream.close();
changetoy()方法
changetoy()方法首先透過傳遞一個引數inputstream給datainputstream物件來定位資源的輸入流,使程式能使用readline()方法從流中讀取資料:
datainputstream xfileln =new datainutstream(inputstream);
然後,changetoy()建立輸出管道和輸入管道:
pipeoutstream pipeout = new pipeoutputstream();
pipeinputstream pipeln = new pipedinputsteam(pipeout);
為了能夠使用println()方法輸出修改的後的文字行到管道,程式將輸出管道定位到printstream物件:
printstream printstream = new printstream(pipeout);
現在,程式可以建立將資料從x改變到y的執行緒,該執行緒是ythread類的一個物件,他傳遞兩個引數:輸入檔案(xfileln)和輸出管道(呼叫printstream)
ythread ythread =new thread(xfileln,printstream);
之後,程式啟動執行緒:
changetoz()方法
changetoz()方法與changetoy()方法很相似,他從changetoy()返回的輸入流開始:
datainputstream yfileln= new datainputstream(inputstream);
程式建立一個新的管道:
pipedoutstream pipeout2 = new pipedoutputstream();
pipedinputstream pipeln2 = new pipedinputsream(pipeout2);
該執行緒透過這個新的管道發出修改後的資料(輸入流pipeln2)給主程式。
源程式如下:
//
//pipeapp.java-pipeapp的主應用程式
//
import java.io.*
class pipeapp
{
public static void main(string[] args)
{
pipeapp pipeapp=new pipeapp();
try
{
fileinputstream xfile =new fileinputstream("input.txt");
inputstream ylnpipe = pipeapp.changetoy(xfileln);
inputstream zlnpipe=pipeapp.changetoz(ylnpipe);
system.out.println();
system.out.println("here are the results");
system.out.pringln();
datainputstream inputstream = nes datainputstream(zlnpipe);
string str = inputstream.readline();
while (str!=null)
{
system.out.println(str);
str=inputstream.readline();
}
inputstream.close();
}
catch(exception e)
{
system.out.println(e.tostring());
}
}
public inputstream changetoy(inputstream inputstream)
{
try
{
datainputstream pipeout = new datainputsteam(inputstream);
pipedoutstream pipeout = new pipedoutputstream();
pipedlnsteam pipeln = new pipedlnputstream(pipeout);
printstream printstream = new printstream(pipeout);
ythread ythread = new ythread(xfileln,printstream);
ythread.start();
return pipeln;
}
catch(exeption e)
{
system.out.println(x.tostring());
}
return null;
}
public inputstream changetoz(inputstream inputsteam)
{
try
{
datainputstream yfileln = new datainputstream(inputstream);
pipeoutputstream pipeln2 = new pipedinputstream(pipeout2);
printrstream printstream2 = new printsteam(pipeout2);
zthread zthread = new zthread(yfileln,printstream2);
zthread.start();
return pipeln2;
}
catch(exception e)
{
system.out.println(e.tostring());
}
return null;
}
}
Ythread類和Zthread類
由於ythread類與zthread類基本一樣,在此僅以ythread為例加以說明。
Ythread的構造器接收兩個引數:輸入的檔案和第一個管道的輸出端,構造器儲存這兩個引數作為類的資料成員:
Ythread(datainputstream xfileln,pringstream printstream)
{
this.xfileln = xfileln;
this.printstream = printstream;
}
執行緒透過run()方法來處理資料。首先讀取一行資料,確保xstring不為空的情況下迴圈執行:
string xstring = xfileln.readline();
每讀一行資料,完成一次轉換
string ystring = xstring.replace(´x´,´y´);
然後將修改後的資料輸出到管道的輸出端:
prinstream.prinrln(ystring);
為了確保所有緩衝區的資料完全進入管道的輸出端:
pringstram.flush();
迴圈完成後,執行緒關閉管道輸出流:
pringstram.close();
ythread類的源程式如下:
//
//ythread.java
//
import java.io.*;
class ythread exteads thread
{
datainputstream xfileln;
pringstream printstream;
ythread(datainputstream xfileln,pringstream.printstream)
{
this.xfileln = xfileln;
this.printstream = printstream;
}
public void run()
{
try
{
string xstring = xfileln.readline();
while(xstring!=null)
{
string ystring= xstring.replace(´x´,´y´);
printstream.pringln(ystring);
printstream.flush();
xstring= xfileln.readline();
}
printstream.close();
}
catch{ioexception e}
{
system.out.println(e.tostring());
}
}
}
pipeapp應用程式使用microsoft visual j++1.1編譯
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-958524/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java的通過管道來實現執行緒通訊Java執行緒
- java多執行緒5:執行緒間的通訊Java執行緒
- java多執行緒間的通訊Java執行緒
- 說說Java執行緒間通訊Java執行緒
- Java-執行緒間通訊小結Java執行緒
- 【Java】【多執行緒】兩個執行緒間的通訊、wait、notify、notifyAllJava執行緒AI
- Java多執行緒-執行緒通訊Java執行緒
- Java中的執行緒通訊詳解Java執行緒
- 利用管道Pipelines做程序間的通訊
- Java執行緒通訊Java執行緒
- Android執行緒間通訊Android執行緒
- Java 執行緒間通訊 —— 等待 / 通知機制Java執行緒
- 利用訊號量實現執行緒順序執行執行緒
- 多執行緒之間的通訊執行緒
- JUC之執行緒間的通訊執行緒
- 利用windows api實現程式通訊(命名管道)WindowsAPI
- Java之執行緒通訊Java執行緒
- 多執行緒之間通訊及執行緒池執行緒
- Java中實現執行緒的方式Java執行緒
- Java多執行緒學習——執行緒通訊Java執行緒
- Android小知識-Java多執行緒相關(執行緒間通訊)上篇AndroidJava執行緒
- java多執行緒:執行緒間通訊——生產者消費者模型Java執行緒模型
- Java多執行緒中的wait/notify通訊模式Java執行緒AI模式
- Android中的執行緒通訊Android執行緒
- iOS GCD執行緒之間的通訊iOSGC執行緒
- Java多執行緒學習(五)執行緒間通訊知識點補充Java執行緒
- juc包:使用 juc 包下的顯式 Lock 實現執行緒間通訊執行緒
- 【JAVA併發第三篇】執行緒間通訊Java執行緒
- Java多執行緒學習(3)執行緒同步與執行緒通訊Java執行緒
- Java中如何實現執行緒呢?Java執行緒
- Java執行緒(九):Condition-執行緒通訊更高效的方式Java執行緒
- 匿名管道通訊實現
- 執行緒間通訊_等待/通知機制執行緒
- Android開發之執行緒間通訊Android執行緒
- 管道流間的通訊
- Java多執行緒的實現Java執行緒
- JAVA - 基於Socket的多執行緒通訊Java執行緒
- Java 執行緒池中的執行緒複用是如何實現的?Java執行緒
- java執行緒實現方式Java執行緒