Каналы обмена информацией
В предыдущей главе мы видели, каких трудов стоит организовать правильный обмен информацией между подпроцессами. В пакете java.io есть четыре класса pipedxxx, облегчающие эту задачу.
В одном подпроцессе-источнике информации – создается объект класса PipedWriter+ или PipedOutputstream, в который записывается информация методами write () этих классов.
В другом подпроцессе-приемнике информации – формируется объект класса PipedReader или Pipedinputstream. Он связывается с объектом-источником с помощью конструктора или специальным методом connect (), и читает информацию методами read ().
Источник и приемник можно создать и связать в обратном порядке.
Так создается однонаправленный канал (pipe) информации. На самом деле это некоторая область оперативной памяти, к которой организован совместный доступ двух или более подпроцессов. Доступ синхронизируется, записывающие процессы не могут помешать чтению.
Если надо организовать двусторонний обмен информацией, то создаются два канала.
В листинге 18.5 метод run () класса source генерирует информацию, для простоты просто целые числа k, и передает £е в канал методом pw.write (k). Метод run() класса Target читает информацию из канала методом pr.read(). Концы канала связываются с помощью конструктора класса Target. На рис. 18.6 видна последовательность записи и чтения информации.
Листинг 18.5. Канал обмена информацией.
import java.io.*; class Target extends Thread{ private PipedReader pr; Target(PipedWriter pw){ try{ pr = new PipedReader(pw); }catch(lOException e){ System.err.println("From Target(): " + e); } } PipedReader getStream(){ return pr;} public void run(){ while(true) try{ System.out.println("Reading: " + pr.read()); }catch(IOException e){ System.out.println("The job's finished."); System.exit(0); } } } class Source extends Thread{ private PipedWriter pw; Source (){ pw = new PipedWriter(); } PipedWriter getStream(){ return pw;} public void run(){ for (int k = 0; k < 10; k++) try{ pw.write(k); System.out.println("Writing: " + k); }catch(Exception e){ System.err.printlnf"From Source.run(): " + e); } } } class PipedPrWr{ public static void main(String[] args){ Source s = new Source(); Target t = new Target(s.getStream()); s.start(); t.start(); } )
Рис. 18.6. Данные, передаваемые между подпроцессами