Reputation: 11678
I have a Thread pool in my Java.NIO socket server.
I sometimes received runtime errors like Connection reset by peer
or Broken Pipe
, etc.
My question is: is the thread getting killed when an exception is thrown? If it is - is a new thread created in the thread pool in place of the killed thread??
This is my ThreadManager:
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadsManager {
private ExecutorService threadPool = null;
private LiveConnectionsManager liveConnectionsManager;
private int threadPoolSize = 35; //number of tasks thread
public ThreadsManager(LiveConnectionsManager liveConnectionsManager) {
this.liveConnectionsManager = liveConnectionsManager;
threadPool = Executors.newFixedThreadPool(threadPoolSize);
ServerActions.threadPool = threadPool;
}
public void processNewMessage(SocketChannel socketChannel, Client client)
{
threadPool.execute(new MessagesProcessor(socketChannel, client, liveConnectionsManager));
}
public void closeConnection(SocketChannel socketChannel, Client client) {
threadPool.execute(new LogoutClient(socketChannel, client, null));
}
}
Upvotes: 8
Views: 8053
Reputation: 10677
As you using ExecutorService to create thread pool.
So yes, ExecutorService.newFixedThreadPool(..) ensures that number of threads are constant if they get killed by any exception/error and there are enough task waiting for thread. Below text from java doc states it clearly :
Straight from java doc :newFixedThreadPool
Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)
Upvotes: 12
Reputation: 4051
The ThreadPoolExecutor
does manage the number of threads based on the settings that you choose (passed in the constructor or via the helper method that you've used). It works just like described in ThreadPoolExecutor javadoc.
From the constructor (listed below) the most interesting parameters are corePoolSize
and maximumPoolSize
. corePoolSize
is the lowest amount of threads that will remain alive. If a thread is killed and due to this the number of threads drop down below this number, new thread(s) will be started[1] (at some point).
maximumPoolSize
is the max numbers of the threads in the pool. If this is higher than corePoolSize
, your pool might end up with more threads then you've specified in corePoolSize
parameter. If one of the threads die at this point and the number of live threads will not drop below corePoolSize
number, then a new thread will NOT be created.
The fixed thread pool that you are creating via the Executors helper class has corePoolSize == maximumPoolSize, so indeed the service will make sure that the same amount of threads is always available[1] (when needed).
[1] An important notice is that the creation of the threads happens "on demand" - that is if a thread dies and there are no tasks in queue, then the thread will not be created until it will not be needed (by enqueuing above already available threads).
/**
* Creates a new <tt>ThreadPoolExecutor</tt>( ... cut irelevant part ... )
*
* @param corePoolSize the number of threads to keep in the
* pool, even if they are idle.
* @param maximumPoolSize the maximum number of threads to allow in the
* pool.
* ( ... cut irelevant part ... )
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
[EDIT] - forgot the other question. Indeed, Exceptions do kill Worker threads - you need to handle errors internally. For details check java.util.concurrent.ThreadPoolExecutor.Worker class. Its runTask method is worth checking.
Upvotes: 4
Reputation: 122364
My question is: does the Thread getting killed when an error is catched ?
and if it does - the thread pool fills it position in the pool with the new thread ?
The executor created by Executors.newFixedThreadPool
will create a new thread if one of the threads in the pool dies, so the answer to the second part of your question is yes. As for the first part, it's impossible to say without seeing the code of MessagesProcessor
and LogoutClient
, but given that any dead threads will be replaced, it doesn't really matter one way or the other. If MessagesProcessor
and LogoutClient
catch and log the exceptions internally
public void run() {
try {
// do stuff
} catch(Exception e) {
e.printStackTrace();
}
}
then the exception won't propagate out of the run
method so won't kill the thread that is running the task, so it will be able to return to the pool. But if they don't catch the exceptions, and they allow a RuntimeException
to be thrown out of the run
method then the thread will die (and be replaced by a fresh one).
Upvotes: 0