熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java 中利用管道實現線程間的通訊

2013-11-23 19:49:07  來源: 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++編譯

From:http://tw.wingwit.com/Article/program/Java/gj/201311/27508.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.