Почему поток-получатель ничего не получает в моей программе потоковой передачи по конвейеру Java?

У меня 3 очень маленьких класса.

Основной класс:

import java.io.*;

public class ConnectionManager {
    public static void main(String argv[]) {

        try {
            PipedOutputStream pout = new PipedOutputStream();
            PipedInputStream pin = new PipedInputStream(pout);

            Sender s = new Sender(pout, true);
            Receiver r = new Receiver(pin, true);
            System.out.println("Starting threads");
            s.start();
            r.start();
        } catch (Exception e) {}
    }
}

Класс Sender

import java.io.*;
import java.util.Random;

public class Sender extends Thread {
    ObjectOutputStream oos;
    boolean primitive;

    public Sender(OutputStream os, boolean primitive) {
        try {
            oos = new ObjectOutputStream(os);
        } catch (Exception e) {}
        this.primitive = primitive;
    }

    public void run() {
        Random rand = new Random();
        while (true) {
            try {
                System.out.println("Integer is being sent");
                oos.writeInt(10);
                Thread.sleep(1000);
            } catch (Exception e) {}
        }
    }
}

И класс Receiver

import java.io.*;

public class Receiver extends Thread {
    ObjectInputStream ois;
    boolean primitive;

    public Receiver(InputStream is, boolean primitive) {
        try {
            ois = new ObjectInputStream(is);
        } catch (Exception e) {}
        this.primitive = primitive;
    }

    public void run() {
        System.out.println("Receiver is starting");
        while (true) {
            try {
                int x = ois.readInt();
                System.out.print("An int was read: " + x);
            } catch (Exception e) {}
        }
    }
}

Пожалуйста, игнорируйте, казалось бы, неиспользуемые переменные, такие как primitive и rand. Это пережитки немного разных версий, которые я тестировал ранее, и мне было лень их удалить.

В любом случае, когда я запускаю основной метод в ConnectionManager, я получаю на выходе следующее:

Starting threads
Receiver is starting
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
//... ad infinitum 

Почему поток получателя не получает сообщения, которые передаются по конвейеру? Что мне здесь не хватает?


person Manuel    schedule 26.04.2017    source источник
comment
Везде, где есть catch (Exception e) {}, замените его на catch (Exception e) {e.printStackTrace (); }   -  person opensam    schedule 26.04.2017
comment


Ответы (1)


В вашем коде есть исключение типа java.io.IOException: Read end dead.

Вы НЕ можете обнаружить, потому что подавляете их с помощью пустых catch блоков.

Главное, что вам нужно изменить классы Sender и Receiver, чтобы использовать PipedOutputStream и PipedInputStream, как показано ниже:

Класс отправителя:

public class Sender extends Thread {
    PipedOutputStream oos;

    public Sender(PipedOutputStream os) {
        try {
            this.oos = os;
        } catch (Exception e) {System.out.println(e);}
    }

    public void run() {
        try {
                System.out.println("Integer is being sent");
                oos.write(10);
                oos.close();
                Thread.sleep(1000);
            } catch (Exception e) {System.out.println(e);}
        }
}

Класс получателя:

public class Receiver extends Thread {
    PipedInputStream ois;
    public Receiver(PipedInputStream is) {
        try {
            this.ois = is;
        } catch (Exception e) {System.out.println(e);}
    }

    public void run() {
        System.out.println("Receiver is starting");
          try {
                int x = ois.read();
                System.out.print("An int was read: " + x);
            } catch (Exception e) {System.out.println(e);}
    }
}

метод main ():

public static void main(String[] args) throws Exception {
         try {
                PipedOutputStream pout = new PipedOutputStream();
                PipedInputStream pin = new PipedInputStream(pout);

                Sender s = new Sender(pout);
                Receiver r = new Receiver(pin);
                System.out.println("Starting threads");
                s.start();
                r.start();
            } catch (Exception e) {
                System.out.println(e);
            }
     }

ВЫХОД:

Starting threads
Receiver is starting
Integer is being sent
An int was read: 10

В качестве примечания помните, что пустые catch блоки - очень плохая практика, поскольку они скрывают исключения, поэтому я настоятельно рекомендую не использовать их в коде.

person developer    schedule 26.04.2017
comment
Привет, спасибо за ваш ответ, но одна из моих целей - иметь возможность отправлять определенные типы данных, а не просто int. Я не думал, что смогу, скажем, отправить двойное или логическое значение с помощью PipedOutputStream. ObjectOutputStream поддерживает такие методы, как writeInt (), writeDouble (), writeBoolean () и т. Д. Edit: спасибо за подсказку по пустым блокам catch. - person Manuel; 26.04.2017