Reputation: 19925
I have a simple ServerSocket-based java program which accepts a client connection and puts it in a threadpool (ThreadPoolExecutor):
while() {
socket = serverSocket.accept();
pool.submit(new Client(socket)); // Client is a Runnable
}
Problem is when I try to shutdown the program and client threads stay around until the connection is closed on the other end (the jvm does not exit until then).
I could try to maintain all client objects and close all their sockets when server is about to shutdown. But I have no clue how maintain them? Especially removing them when done.
I tried beforeExecute etc, but that only gives me another object (a FutureTask), not the Client object I'm looking for.
Update:
The problem is not adding sockets to a list, the problem is removing them when they are done as there are no way (afaik) to use afterExecute for that.
Upvotes: 3
Views: 2200
Reputation: 19925
One way is to to have the Client return itself (in the Future) when done. Just need a list and then use the afterExecute method.
Like this:
pool =new ThreadPoolExecutor(...) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
// The future returns the Client object!
client = (Client)((FutureTask)r).get();
// Remove it from list of known clients
clients.remove(client);
}
};
while() {
socket = serverSocket.accept();
Client client = new Client(socket)
// Submit to pool, using client as the future return value
pool.submit(client, client);
// Add to list of known clients
clients.add(client);
}
// When app is closing
private shutdown() {
for(Client client : clients){
client.shutdown();
}
}
Upvotes: 1
Reputation: 311039
Call shutdownInput() on all the client sockets. That will cause the associated threads to think that the peer has disconnected and so exit gracefully.
Upvotes: 0
Reputation: 8938
Store all the sockets in a List
before submitting them to the pool. Then the shutdown thread can call close()
on all the sockets, which should cause the blocked threads to throw SocketException
s.
Upvotes: 1