Java 中利用管道實現(xiàn)線程間的通訊
更新時間: 2007-05-31 14:03:27來源: 粵嵌教育瀏覽量:788
在Java 語言中,提供了各種各樣的輸入輸出流(stream),使我們能夠很方便的對數(shù)據(jù)進行操作,其中,管道(pipe)流是一種特殊的流,用于在不同線程(threads)間直接傳送數(shù)據(jù)。一個線程發(fā)送數(shù)據(jù)到輸出管道,另一個線程從輸入管道中讀數(shù)據(jù)。通過使用管道,實現(xiàn)不同線程間的通訊。無需求助于類似臨時文件之類的東西。本文在簡要介紹管道的基本概念后,將以一個具體的實例pipeapp加以詳細說明。
1.管道的創(chuàng)建與使用
Java提供了兩個特殊的專門的類專門用于處理管道,它們就是pipedinputstream類和pipeoutputstream類。
Pipedinputstream代表了數(shù)據(jù)在管道中的輸出端,也就是線程向管道讀數(shù)據(jù)的一端;pipeoutputstream代表了數(shù)據(jù)在管道中的輸入端,也就是線程向管道寫數(shù)據(jù)的一端,這兩個類一起使用可以提供數(shù)據(jù)的管道流。
為了創(chuàng)建一個管道流,我們必須首先創(chuàng)建一個pipeoutstream對象,然后,創(chuàng)建pipeinputstream對象,實例如下:
pipeout= new pipedyoutstream();
pipein= new pipedputsteam(pipepout);
一旦創(chuàng)建了一個管道后,就可以象操作文件一樣對管道進行數(shù)據(jù)的讀寫。
2.演示程序: pipeapp
應(yīng)用程序由三個程序組成:主線程(pipeapp.Java)及由主線程啟動的兩個二級線程(ythread.Java和zthread.Java),它們使用管道來處理數(shù)據(jù)。程序從一個內(nèi)容為一行一行"x"字母的"input.txt"文件中讀取數(shù)據(jù),使用管道傳輸數(shù)據(jù),次是利用線程ythread將數(shù)據(jù)"x"轉(zhuǎn)換為"y",利用線程zthread將"y"轉(zhuǎn)換為"z",之后,程序在屏幕上顯示修改后的數(shù)據(jù)。
主線程 (pipeapp.Java)
在main()方法中,程序首先創(chuàng)建一個應(yīng)用對象:pipeapp pipeapp=new pipeapp();
由于程序中流操作都需要使用IOException異常處理,所以設(shè)置了一個try塊。在try中,為了從源文件中讀取數(shù)據(jù),程序為"input.txt"文件創(chuàng)建了一個輸入流Xfileln,:
fileinputstream xfileln= new fileinputstream("input.txt");
新的輸入流傳遞給changetoy()方法,讓線程ythread能讀取該文件:
inputstream ylnpipe =pipeapp.changetoy(xfileln);
changetoy()方法創(chuàng)建將輸入數(shù)據(jù)"x"改變到"y"的線程ythread,并返回該線程的輸入管道:
inputstream zlnpipe = pipeapp.changetoz(ylnpipe);
changetoz()方法啟動將數(shù)據(jù)從"y"改變到"z"的線程zehread,主程序?qū)⑹褂脧腸hangetoz()返回的輸入管道。得到以修改的數(shù)據(jù)。
然后,程序?qū)⒐艿垒斎肓鞫ㄎ坏絛atainputstream對象,使程序能夠使用readline()方法讀取數(shù)據(jù):
datainputstream inputstream = new datainputstream(zlnpiepe);
創(chuàng)建了輸入流以后,程序就可以以行一行的讀取數(shù)據(jù)病顯示在屏幕上。
String str= inputstream.readline();
While(str!=null)
{
system.out.println(str); str=inputstream.readline();
}
顯示完成之后,程序關(guān)閉輸入流:
inputstream.close();
changetoy()方法
changetoy()方法首先通過傳遞一個參數(shù)inputstream給datainputstream對象來定位資源的輸入流,使程序能使用readline()方法從流中讀取數(shù)據(jù):
datainputstream xfileln =new datainutstream(inputstream);
然后,changetoy()創(chuàng)建輸出管道和輸入管道:
pipeoutstream pipeout = new pipeoutputstream();
pipeinputstream pipeln = new pipedinputsteam(pipeout);
為了能夠使用println()方法輸出修改的后的文本行到管道,程序?qū)⑤敵龉艿蓝ㄎ坏絧rintstream對象:
printstream printstream = new printstream(pipeout);
現(xiàn)在,程序可以創(chuàng)建將數(shù)據(jù)從x改變到y(tǒng)的線程,該線程是ythread類的一個對象,他傳遞兩個參數(shù):輸入文件(xfileln)和輸出管道(調(diào)用printstream)
ythread ythread =new thread(xfileln,printstream);
之后,程序啟動線程:
changetoz()方法
changetoz()方法與changetoy()方法很相似,他從changetoy()返回的輸入流開始:
datainputstream yfileln= new datainputstream(inputstream);
程序創(chuàng)建一個新的管道:
pipedoutstream pipeout2 = new pipedoutputstream();
pipedinputstream pipeln2 = new pipedinputsream(pipeout2);
該線程通過這個新的管道發(fā)出修改后的數(shù)據(jù)(輸入流pipeln2)給主程序。
源程序如下:
//
//pipeapp.Java-pipeapp的主應(yīng)用程序
//
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的構(gòu)造器接收兩個參數(shù):輸入的文件和個管道的輸出端,構(gòu)造器存儲這兩個參數(shù)作為類的數(shù)據(jù)成員:
Ythread(datainputstream xfileln,pringstream printstream)
{
this.xfileln = xfileln;
this.printstream = printstream;
}
線程通過run()方法來處理數(shù)據(jù)。首先讀取一行數(shù)據(jù),確保xstring不為空的情況下循環(huán)執(zhí)行:
string xstring = xfileln.readline();
每讀一行數(shù)據(jù),完成一次轉(zhuǎn)換
string ystring = xstring.replace('x','y');
然后將修改后的數(shù)據(jù)輸出到管道的輸出端:
prinstream.prinrln(ystring);
為了確保所有緩沖區(qū)的數(shù)據(jù)完全進入管道的輸出端:
pringstram.flush();
循環(huán)完成后,線程關(guān)閉管道輸出流:
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應(yīng)用程序使用microsoft visual j++1.1編譯
推薦閱讀
- ·Linux字符設(shè)備驅(qū)動框架解析:file_operations的核心作用與實現(xiàn)
- ·廣東朝歌數(shù)碼科技股份有限公司專場招聘會
- ·深化產(chǎn)教融合,共筑技能人才培養(yǎng)新生態(tài) —— 廣州華立學(xué)院到訪粵嵌從化校區(qū)為深化產(chǎn)教
- ·校企合作新突破 | 粵嵌科技與三亞學(xué)院共探產(chǎn)教融合新路徑
- ·粵嵌科技入選國家級職業(yè)數(shù)字展館聯(lián)合建設(shè)單位,賦能計算機程序設(shè)計員高技能人才培養(yǎng)
- ·嵌入式實時操作系統(tǒng)的性能優(yōu)化與實現(xiàn)路徑
- ·校企攜手賦能教育!粵嵌科技助力海南科技職業(yè)大學(xué)探索 AGI 時代教學(xué)新范式
- ·嵌入式系統(tǒng)中的低功耗設(shè)計策略與實現(xiàn)路徑
- ·深圳市軒宇軟件開發(fā)有限公司專場招聘會
- ·嵌入式系統(tǒng)中的代碼空間優(yōu)化:策略與實踐