1

I have an app that listens to incoming connections on a specified hostname and port. The listening is invoked with the method listen() (see below), which waits constantly for an incoming connection using ServerSocket.accept(), creating a new Thread to handle the input stream.

private ServerSocket serverSocket;
private Thread listenerThread;

public void listen() throws IOException {
    this.listenerThread = new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                try {
                    Socket socket = TheServerClass.this.serverSocket.accept();
                    // Create new thread to handle the incoming connection
                }
                catch (IOException exc) { }
            }
        }
    });
    this.listenerThread.start();
}

Now I want to stop the running of listenerThread. But when I call this.listenerThread.interrupt(), this doesn't work.
I thought you can stop a thread by interrupting it, so why isn't that working?

(Notice: A possible solution is to close the ServerSocket using this.serverSocket.close(), but can it be accomplished with interrupt() or something?)

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • As you point out, when using standard sockets, this is only possible by closing the socket. There are several questions here on SO dealing with same problem, e.g. http://stackoverflow.com/questions/1510403/how-to-unblock-a-thread-blocked-on-serversocket-accept – Peter Štibraný Jan 11 '12 at 11:57
  • What do you mean by it doesn't work? Does it throw any exceptions? Or just continue usually? – mohdajami Jan 11 '12 at 12:01
  • @medopal The thread just continues running without terminating it. – MC Emperor Jan 11 '12 at 12:05

3 Answers3

1

The answer is in the question. You need to close the socket. It's done using serverSocket.close(). Thread.interrupt() doesn't care about sockets.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

Call serverSocket.close(),

I guess since you are not doing IO yet - you can not interrupt it, and since the accept() doesn't throw InterruptedException you won't be able to interrupt it. The thread is interrupted, but that flag you have to check for yourself Thread.isInterrupted().

See How can I interrupt a ServerSocket accept() method?.

Community
  • 1
  • 1
polve
  • 2,789
  • 2
  • 18
  • 20
  • Since `accept()` can't be interrupted (which is a little bit weird in my opinion, but so be it), I suppose I have to use `close()`... Thanks for the help! – MC Emperor Jan 11 '12 at 12:07
0

Use this:

public class MyThread extends Thread {

    private boolean stop;
    private ServerSocket serverSocket;

    public MyThread(ServerSocket ss) {
        this.serverSocket = ss;
        this.stop = false;
    }

    public void setStop() {
        this.stop = true;
        if (this.ss != null) {
            this.ss.close();
        }
    }

    public void run() {
        while (!stop) {
            try {
                Socket socket = serverSocket.accept();
                // Create new thread to handle the incoming connection 
            }
            catch (IOException exc) { }
        }
    }
}

and from the listen() method just call setStop() method of the thread.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
xyz
  • 211
  • 1
  • 3
  • Not good. You should at least declare `stop` as volatile, otherwise the compiler may optimize it in such way, that different threads would see different values. – ivant Aug 13 '14 at 13:26