如何停止线程等待输入

时间:2018-08-24 09:14:30

标签: java multithreading sockets

我的程序上有一个侦听器线程,它只是在等待服务器的输入。因此,他收到一条消息,将其放入队列中,然后等待另一条消息。因此,无法按照其他类似主题中提出的方式关闭它,因为他需要在测试While条件之前从服务器接收消息。

这里是:

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();
        }
    }
}

所以基本上,当我关闭套接字时,ois.readUTF将抛出EOFException。 我该怎么做才能正确停止此流而不会出现此异常?

我发现的唯一方法是,当客户端想要停止连接(并因此关闭套接字)时,他可以向服务器发送一条消息(例如“再见”或其他),然后服务器将回答“再见”,当我的听众收到再见时,他将关闭套接字,这将使他退出while循环并停止。我认为应该运作良好。但是我想知道是否还有另一种方法(某种程度上我对我的想法不太满意)。

1 个答案:

答案 0 :(得分:1)

最好的方法是使用NIO API提供的非阻塞IO API。这将需要对这段代码进行不重要的更改。

最简单的方法是在关闭套接字之前设置一些标志isFinishing。然后,等待线程应检查该标志是否在catch子句中设置。如果是这种情况,则可以放心地忽略EOFException。如果您采用这种方式,请确保isFinishing已正确同步(易失性或更佳的CountDownLatch)。