Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Помогите разобраться с PipedOutputStream/PipedInputStream / 2 сообщений из 2, страница 1 из 1
16.06.2020, 14:31
    #39969772
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с PipedOutputStream/PipedInputStream
Есть код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
package pipesStream;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeExample {

    public static void main(String[] args) throws IOException, InterruptedException {

        final PipedOutputStream output = new PipedOutputStream();
		final PipedInputStream  input  = new PipedInputStream(output);

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                	for (int i=0; i<100;i++) {
                		System.out.println("Write " + i+":");
                		output.write("Hello world!".getBytes());
                	}
                } catch (Exception e) {
                	System.out.println(e);
                }
            }
        });


        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int data = input.read();
                    while(data != -1){
                        System.out.print((char) data);
                        data = input.read();
                    }
                } catch (IOException e) {
                	System.out.println(e);
                }
            }
        });

        thread1.start();
        thread2.start();
        
        thread1.join();
        thread2.join();

        output.close();
        input.close();
    }
}



1) Выполнение потока "thread2" может завершиться только когда "input.read()" вернет "-1".
2) Метод "PipedInputStream.read()" вернет -1 только в случае, когда значение переменной closedByWriter = .T.:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
    public synchronized int read()  throws IOException {
        if (!connected) {
            throw new IOException("Pipe not connected");
        } else if (closedByReader) {
            throw new IOException("Pipe closed");
        } else if (writeSide != null && !writeSide.isAlive()
                   && !closedByWriter && (in < 0)) {
            throw new IOException("Write end dead");
        }

        readSide = Thread.currentThread();
        int trials = 2;
        while (in < 0) {
            if (closedByWriter) {
                /* closed by writer, return EOF */
                return -1;
            }
            if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
                throw new IOException("Pipe broken");
            }
            /* might be a writer waiting */
            notifyAll();
            try {
                wait(1000);
            } catch (InterruptedException ex) {
                throw new java.io.InterruptedIOException();
            }
        }
        int ret = buffer[out++] & 0xFF;
        if (out >= buffer.length) {
            out = 0;
        }
        if (in == out) {
            /* now empty */
            in = -1;
        }

        return ret;
    }


3) Значение переменной closedByWriter может быть изменено только в методе PipedInputStream.receivedLast():
Код: java
1.
2.
3.
4.
    synchronized void receivedLast() {
        closedByWriter = true;
        notifyAll();
    }


4) Метод PipedInputStream.receivedLast() можно вызвать только в классе PipedOutputStream в методе PipedOutputStream.close():
Код: java
1.
2.
3.
4.
5.
    public void close()  throws IOException {
        if (sink != null) {
            sink.receivedLast();
        }
    }


5) Но метод output.close() в главном примере вызывается после того как отработают оба потока (thread1.join и thread2.join ожидают завершения выполнения потоков).

Не понимаю, где у меня ошибка в рассуждениях? Каким образом PipedInputStream узнает, что данные закончились?
...
Рейтинг: 0 / 0
16.06.2020, 16:15
    #39969826
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с PipedOutputStream/PipedInputStream
Разобрался:
Сначала думал, что код отрабатывает нормально, но оказалось, что этот код в любом случае бросает exception ("Write and dead" или "Pipeline broken").

Сообщение об ошибке затерялось в логах, сразу не заметил.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Помогите разобраться с PipedOutputStream/PipedInputStream / 2 сообщений из 2, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]