ПОЧЕМУ при работе с сокетами мы должны Создать объект класса ObjectOutputStream нужно до того, как будет создаваться объект класса ObjectInputStream, иначе может возникнуть взаимная блокировка потоков
Вроде нашел ответ на stascowerflow, но не могу внятно перевести
https://stackoverflow.com/questions/14110986/new-objectinputstream-blocks
public class Connection implements Closeable {
private final Socket socket;
private final ObjectOutputStream out;
private final ObjectInputStream in;
public Connection(Socket socket) throws IOException {
this.socket = socket;
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
}
public void send(Message message) throws IOException{
synchronized (out) {
out.writeObject(message);
out.flush();
}
}
public Message receive() throws IOException, ClassNotFoundException{
synchronized (in) {
return (Message) in.readObject();
}
}
@Override
public void close() throws IOException {
out.close();
in.close();
socket.close();
}
public SocketAddress getRemoteSocketAddress(){
return socket.getRemoteSocketAddress();
}
}
ObjectInputStreamконструктор пытается прочитать из нижележащего стрима специальный заголовок. Пока этот заголовок не будет прочитан, конструктор управление не вернёт. Поэтому если конструкторObjectOutputStream, который, собственно, и пишет этот заголовок в нижележащий стрим, вызывается не в другом потоке управления, то он должен быть вызван до того, как будет вызван конструкторObjectInputStream, иначе конструкторObjectInputStreamникогда не возвратит управления, а будет вечно ждать появления заголовка в нижележащем стриме.