Reputation: 899
I would like to shutdown a server when countDownLatch.getCount()
is zero, but instead of shutting down, it waits on accepting socket connection. Here is the server code that handles incoming TCP requests.
public static void start(File configFile, ReplyListener replyListener, CountDownLatch countDownLatch) {
try {
Server.init(configFile);
while (countDownLatch.getCount() != 0) {
//try {
Server.socket = serverSocket.accept();
Message message = new Message();
message.setSocket(Server.socket);
Server.pool.submit(new ServerTaskCallable(message.receive()).setReplyListener(replyListener));
/*} catch (SocketTimeoutException e){
System.out.println("Finished testing");
}*/
}
Server.socket.close();
serverSocket.close();
Server.pool.shutdownNow();
} catch (IOException e) {
logger.error("Cannot start a server. The server thread will be terminated. Exception: ", e);
System.exit(0);
}
}
Here is the thread dum:
"pool-1-thread-1@651" prio=5 tid=0xe nid=NA runnable
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(PlainSocketImpl.java:-1)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at model.server.Server.start(Server.java:42)
at model.MainTest.lambda$main$3(MainTest.java:30)
at model.MainTest$$Lambda$2.2012232625.run(Unknown Source:-1)
at java.lang.Thread.run(Thread.java:745)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
"pool-3-thread-1@1142" prio=5 tid=0x12 nid=NA waiting
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
How can I terminate properly the server thread pool?
Upvotes: 2
Views: 759
Reputation: 15146
You have two options:
Set a timeout on the ServerSocket
via ServerSocket#setSoTimeout(int)
. This will cause accept()
to throw a SocketTimeoutException
everytime the timeout occurs. You will need to catch the exception inside your loop to ensure your server keeps listening for connections:
while(countDownLatch.getCount() != 0) {
try {
socket = serverSocket.accept();
} catch(SocketTimeoutException e) {
//timeout occurred!
}
}
Close the ServerSocket
via ServerSocket#close()
from a different thread. This will throw a SocketAcception
, terminating the accept()
call. This exception could be caught outside the loop to easily exit the "listen for connections" behavior.
Upvotes: 1