ПОЧЕМУ при работе с сокетами мы должны Создать объект класса 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();
    }
}