Главная » Java » Потоки Piped в Java

0

 

  Канальные потоки (piped streams), определяемые классами семейства Piped — PipedinputStream, PipedOutputstream, PipedReader и Pipedwriter, — используются в виде пар ввода-вывода (записи-чтения); данные, переданные в поток вывода (записи), служат источником для потока ввода (чтения). С каналом (pipe) связан внутренний буфер, емкость которого определяется при реализации класса, что позволяет поддерживать разные уровни производительности процессов вывода и ввода; однако средств динамического управления размером буфера не существует.

    Каналы реализуют механизм обмена данными между различными потоками ‘числений.  Единственный безопасный способ обращения с потоками данных PSd связан с использованием двух потоков вычислений: один из них осущест-яет вывод данных, а другой — их ввод. Когда буфер канала полностью запол-ется, попытка вывода данных в него приводит к блокированию соответствующего потока вычислений.  Если операции вывода и ввода выполняются одним потоком вычислений, тот будет блокирован постоянно. Поток вычислений, осуществляющий ввод, блокируется, если буфер канала пуст.

   Чтобы избежать опасности "вечного" блокирования одного потока вычислений когда его "собрат" на другом конце канала прекращает работу, каждый канал отслеживает подлинность и работоспособность потоков ‘вычислений, обращавшихся к нему с целью вывода и ввода данных последними. Канал, прежде чем блокировать текущий поток вычислений, проверяет, "жив" ли поток на другом конце канала. Если обнаруживается, что работа противоположного потока вычислений прекращена текущий поток генерирует исключение типа IOException.

   Следующий пример демонстрирует применение канальных потоков для обеспечения взаимодействия потока вычислений типа TextGenerator, который, как следует из его названия, призван генерировать текст, с потоком вычислений, получающим такой текст. Прежде всего, приведем код класса-генератора:

 

 

class TextGenerator extends Thread {

 private writer out;

 {

public TextGenerator(writer out){

 this.out = out;

}

public void run () {

 try {

      try {

            for (char с = ‘а'; с <= ‘z’; с++)

                   out.write(c);

      } finally {

         out.closeO;

     }

} catch (IOException e) {

         getThreadGroup().uncaughtException(this, e);

      }

    }

}

Объект TextGenerator осуществляет запись символов в поток, ссылка на который передается конструктору объекта в виде аргумента. В конкретном случае таким потоком может быть поток Piped, данные из которого считываются основным потоком вычислений:

class  Pipe  {

     public static void main(String[]  args)

          throws  IOException

 {

Pipedwriter out = new pipedwriterO;

PipedReader in = new PipedReader(out);

 

      TextGenerator data = new TextGenerator(out);

      data.start();

 

      i nt ch;

      while ((ch = in.read()) != -1)  

      System.out.print((char) ch);

      System.out.println() ;

   }

 }

При создании потоков Piped конструктору потока PipedReader в качестве аргумента передается ссылка на поток Pipedwriter. Впрочем, порядок построения объектов пары потоков Piped несуществен: наоборот, вполне возможно передать конструктору Pipedwriter ссылку на объект PipedReader. Важно то, что объекты потоков Piped должны быть связаны друг с другом. Далее мы создаем объект    TextGenerator,     передавая    его    конструктору    ссылку    на pipedwriter, символьный поток записи, и запускаем поток вычислений, осуществляющий генерирование символов, на выполнение вызовом метода Start. В цикле while выполняется чтение символов, получаемых от генератора текста, и запись их в стандартный поток вывода. Наконец, мы заканчиваем вывод данных символом завершения строки.

  Потоки Piped должны быть соединены, но сделать это можно позже, после их создания, поскольку в составе классов Piped предлагаются и конструкторы без аргументов. Для соединения канальных потоков применяется метод connect. Методу PipedReader.connect в качестве параметра передается объект Pipedwriter, а методу Pipedwriter.connect — PipedReader. Как и при использовании конструкторов, совершенно не важно, присоединяется ли объект х к объекту у или наоборот, у к х, поскольку результат в обоих случаях одинаков. При попытках использования потоков Piped до их соединения или связывания ранее соединенных потоков выбрасывается исключение типа IOException.

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии