java

位置:IT落伍者 >> java >> 浏览文章

Java 中利用管道实现线程间的通讯


发布日期:2024年02月20日
 
Java 中利用管道实现线程间的通讯

在Java 语言中提供了各种各样的输入输出流(stream)使我们能够很方便的对数据进行操作其中管道(pipe)流是一种特殊的流用于在不同线程(threads)间直接传送数据一个线程发送数据到输出管道另一个线程从输入管道中读数据通过使用管道实现不同线程间的通讯无需求助于类似临时文件之类的东西本文在简要介绍管道的基本概念后将以一个具体的实例pipeapp加以详细说明

.管道的创建与使用

Java提供了两个特殊的专门的类专门用于处理管道它们就是pipedinputstream类和pipeoutputstream类

Pipedinputstream代表了数据在管道中的输出端也就是线程向管道读数据的一端pipeoutputstream代表了数据在管道中的输入端也就是线程向管道写数据的一端这两个类一起使用可以提供数据的管道流

为了创建一个管道流我们必须首先创建一个pipeoutstream对象然后创建pipeinputstream对象实例如下

pipeout= new pipedyoutstream();

pipein= new pipedputsteam(pipepout);

一旦创建了一个管道后就可以象操作文件一样对管道进行数据的读写

.演示程序 pipeapp

应用程序由三个程序组成主线程(pipeappJava)及由主线程启动的两个二级线程(ythreadJava和zthreadJava)它们使用管道来处理数据程序从一个内容为一行一行x字母的inputtxt文件中读取数据使用管道传输数据第一次是利用线程ythread将数据x转换为y最后利用线程zthread将y转换为z之后程序在屏幕上显示修改后的数据

主线程 (pipeappJava)

在main()方法中程序首先创建一个应用对象pipeapp pipeapp=new pipeapp();

由于程序中流操作都需要使用IOException异常处理所以设置了一个try块在try中为了从源文件中读取数据程序为inputtxt文件创建了一个输入流Xfileln:

fileinputstream xfileln= new fileinputstream(inputtxt);

新的输入流传递给changetoy()方法让线程ythread能读取该文件

inputstream ylnpipe =pipeappchangetoy(xfileln);

changetoy()方法创建将输入数据x改变到y的线程ythread并返回该线程的输入管道

inputstream zlnpipe = pipeappchangetoz(ylnpipe);

changetoz()方法启动将数据从y改变到z的线程zehread主程序将使用从changetoz()返回的输入管道得到以修改的数据

然后程序将管道输入流定位到datainputstream对象使程序能够使用readline()方法读取数据

datainputstream inputstream = new datainputstream(zlnpiepe);

创建了输入流以后程序就可以以行一行的读取数据病显示在屏幕上

String str= inputstreamreadline();

While(str!=null)

{

systemoutprintln(str);str=inputstreamreadline();

}

显示完成之后程序关闭输入流

inputstreamclose();

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(xfilelnprintstream);

之后程序启动线程

changetoz()方法

changetoz()方法与changetoy()方法很相似他从changetoy()返回的输入流开始

datainputstream yfileln= new datainputstream(inputstream);

程序创建一个新的管道

pipedoutstream pipeout = new pipedoutputstream();

pipedinputstream pipeln = new pipedinputsream(pipeout);

该线程通过这个新的管道发出修改后的数据(输入流pipeln)给主程序

源程序如下

//

//pipeappJavapipeapp的主应用程序

//

import Javaio*

class pipeapp

{

public static void main(string[] args)

{

pipeapp pipeapp=new pipeapp();

try

{

fileinputstream xfile =new fileinputstream(inputtxt);

inputstream ylnpipe = pipeappchangetoy(xfileln);

inputstream zlnpipe=pipeappchangetoz(ylnpipe);

systemoutprintln();

systemoutprintln(here are the results);

systemoutpringln();

datainputstream inputstream = nes datainputstream(zlnpipe);

string str = inputstreamreadline();

while (str!=null)

{

systemoutprintln(str);

str=inputstreamreadline();

}

inputstreamclose();

}

catch(exception e)

{

systemoutprintln(etostring());

}

}

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(xfilelnprintstream);

ythreadstart();

return pipeln;

}

catch(exeption e)

{

systemoutprintln(xtostring());

}

return null;

}

public inputstream changetoz(inputstream inputsteam)

{

try

{

datainputstream yfileln = new datainputstream(inputstream);

pipeoutputstream pipeln = new pipedinputstream(pipeout);

printrstream printstream = new printsteam(pipeout);

zthread zthread = new zthread(yfilelnprintstream);

zthreadstart();

return pipeln;

}

catch(exception e)

{

systemoutprintln(etostring());

}

return null;

}

}

Ythread类和Zthread类

由于ythread类与zthread类基本一样在此仅以ythread为例加以说明

Ythread的构造器接收两个参数输入的文件和第一个管道的输出端构造器存储这两个参数作为类的数据成员

Ythread(datainputstream xfilelnpringstream printstream)

{

thisxfileln = xfileln;

thisprintstream = printstream;

}

线程通过run()方法来处理数据首先读取一行数据确保xstring不为空的情况下循环执行

string xstring = xfilelnreadline();

每读一行数据完成一次转换

string ystring = xstringreplace(xy);

然后将修改后的数据输出到管道的输出端

prinstreamprinrln(ystring);

为了确保所有缓沖区的数据完全进入管道的输出端

pringstramflush();

循环完成后线程关闭管道输出流

pringstramclose();

ythread类的源程序如下

//ythreadJava

//

import Javaio*;

class ythread exteads thread

{

datainputstream xfileln;

pringstream printstream;

ythread(datainputstream xfilelnpringstreamprintstream)

{

thisxfileln = xfileln;

thisprintstream = printstream;

}

public void run()

{

try

{

string xstring = xfilelnreadline();

while(xstring!=null)

{

string ystring= xstringreplace(xy);

printstreampringln(ystring);

printstreamflush();

xstring= xfilelnreadline();

}

printstreamclose();

}

catch{ioexception e}

{

systemoutprintln(etostring());

}

}

}

pipeapp应用程序使用microsoft visual j++编译

               

上一篇:Java 线程的几种状态

下一篇:实战Java多线程编程精要之高级支持