2

I'm writing a client/server application in Java using sockets. In the server, I have a thread that accepts client connections, this thread runs indefinitely. At some point in my application, I want to stop accepting client connection, so I guess destroying that thread is the only way. Can anybody tell me how to destroy a thread?

Here's my code:

class ClientConnectionThread implements Runnable {

    @Override
    public void run() {
        try {
            // Set up a server to listen at port 2901
            server = new ServerSocket(2901);

            // Keep on running and accept client connections
            while(true) {
                // Wait for a client to connect
                Socket client = server.accept();
                addClient(client.getInetAddress().getHostName(), client);

                // Start a new client reader thread for that socket
                new Thread(new ClientReaderThread(client)).start();
            }
        } catch (IOException e) {
            showError("Could not set up server on port 2901. Application will terminate now.");
            System.exit(0);
        }
    }
}

As you can see, I have an infinite loop while(true) in there, so this thread will never stop unless somehow I stop it.

Assim
  • 441
  • 2
  • 6
  • 18
  • 1
    A thread must stop itself in java! – El Hocko Feb 19 '13 at 00:08
  • a thread is usually terminated by issuing an interrupt, as shown [here](http://stackoverflow.com/questions/5915156/how-can-i-kill-a-thread-without-using-stop/5915430#5915430). – mre Feb 19 '13 at 00:15

2 Answers2

3

The right way to do this would be to close the server socket. This will cause the accept() to throw an IOException which you can handle and quit the thread.

I'd add a public void stop() method and make the socket a field in the class.

private ServerSocket serverSocket;

public ClientConnectionThread() {
    this.serverSocket = new ServerSocket(2901);
}
...
public void stop() {
    serverSocket.close();
}
public void run() {
     while(true) {
         // this will throw when the socket is closed by the stop() method
         Socket client = server.accept();
         ...
     }
}
Gray
  • 115,027
  • 24
  • 293
  • 354
  • 3
    To add to this, you will need a reference back to the Runnable to do this. Keeping a list of active Threads would be a good idea. – Tom Feb 19 '13 at 00:10
2

Generally you don't. You ask it to interrupt whatever it is doing using Thread.interrupt().

A good explanation of why is in the Javadoc.

From the link:

Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. (This is the approach that the Java Tutorial has always recommended.) To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized).

It should be noted that in all situations where a waiting thread doesn't respond to Thread.interrupt, it wouldn't respond to Thread.stop either.

For your specific situation you will have to call serverSocket.close, since it does not respond to Thread.interrupt.

syb0rg
  • 8,057
  • 9
  • 41
  • 81
  • Huh? How does that help @syb0rg? – Gray Feb 19 '13 at 00:32
  • For what? Thread? I know it pretty intimately. I don't understand how setting `nameOfThread` to `null` "destroys" the thread. What am I missing? – Gray Feb 19 '13 at 00:37
  • Dude there's a lot more to it than that. THe OP's problem is that his thread is locked in `socket.accept()`. There is no way to break out of that without clocking the server socket. And if you are going to be checking for the variable you might as well just look for `Thread.currentThread().isInterrupted()`. – Gray Feb 19 '13 at 00:40
  • You are right, proper solution has been added. If you could remove your down-vote, I would be grateful. – syb0rg Feb 19 '13 at 00:47
  • The statement about `Thread.stop()` is not true I believe. `Thread.stop()` _will_ work. It's just deprecated and not recommended. – Gray Feb 19 '13 at 00:49