Ablia
Ablia

Reputation: 327

How to stop a Thread waiting for input

I have a Listener Thread on my program, which is just waiting for an Input from Server. So he receive a message, put it in a queue, and wait for another one. Because of this fact, it can't be closed on the way proposed in other similar subjects, because he needs to receive a message from the server before testing the While condition.

Here it is:

public class Listener implements Runnable{

    private Socket socket; 
    private ObjectInputStream ois;


    public Listener(Socket socket) {
        this.socket = socket;
        try {
            this.ois = new ObjectInputStream(socket.getInputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void run() {
        try {
            while(!socket.isClosed()) {
                String type = ois.readUTF();
                System.out.println("received: " +type);
                main.queue.put(type);
            }
        } catch (IOException | InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

So basically, when i close the socket, the ois.readUTF will throw an EOFException. What can i do to properly stop this stream without getting this exception?

The only way i found is, when the client want to stop the connection (and so close the socket), he can send a message to the server (like "goodbye" or whatever), and then the server will answer "goodbye" too, and when my listener receive this goodbye, he'll close the socket, which will make him go out of the while loop and stop. I think it should be working well. But i would like to know if there's another way to do that (somehow i'm not very pleased with my idea).

Upvotes: 1

Views: 766

Answers (1)

The best way to do it is to use non blocking IO API provided by NIO API. This would require to do non trivial changes to this piece of code.

The easy way would be to set some flag isFinishing before closing the socket. Then the waiting thread should check if the flag is set in catch clause. If it is the case then it can safely ignore EOFException. If you go this way make sure isFinishing is properly synchronized (either volatile or better a CountDownLatch).

Upvotes: 1

Related Questions