code-gijoe
code-gijoe

Reputation: 7244

How to 'kill' the threads from an executor?

I have an tomcat webapp where I use a java executor to execute some runnables.

First I allocate the executor service from my executor instance like this:

executorService = Executors.newFixedThreadPool(nThreads, new MyThreadFactory(threadFactoryName))

Then, I launch task using the executor service:

executorService.execute(new MyRunnable);

Then, it seems to work. But my problem is, I am chasing some sort of leak where I get this error after a while of running the server:

Caused by: java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
at java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:703)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652)
at something.server.ThreadExecutor.execute(MyRunnable.java:91)

I used the java VisualVM on tomcat instance to trace the thread allocation. I see that when I call 'newFixedThreadPool' I see 'nThreads' new threads. But after their job is done, I see the state of the threads to be on 'wait'.

Is that normal? I don't believe it is, I know the runnables finish their job but the executor service never frees the threads. What can I do to free them, or am I completely out of scope?

Upvotes: 1

Views: 4623

Answers (3)

Stephen C
Stephen C

Reputation: 719346

Is that normal? I don't believe it is, I know the runnables finish their job but the executor service never frees the threads.

Yes it is normal. Indeed, this behaviour is desirable because creating a new thread is an expensive operation. The pool threads (or at least the 'core' pool threads) will continue to exist until the executor gets shut down.

What can I do to free them, or am I completely out of scope?

You should be able to configure your thread pool to have a smaller 'core' thread pool, and/or a smaller keepAlive time. Refer to the javadoc for details.


[M]y problem is, I am chasing some sort of leak where I get this error after a while of running the server:

That OOME is not necessarily an indication of a leak. It could be a sign that you haven't left enough non-heap memory for the number of threads that you are trying to create. (Or to put it another way, that your thread pool is too big.)

Upvotes: 2

Flavio
Flavio

Reputation: 11977

I think you are instantiating a new ExecutorService for every request, or something like that.

You should either instantiate only one ExecutorService, and reuse it, or call shutdown() on the service after you have finished submitting tasks. The shutdown function will wait for the tasks to finish, and then free the threads.

Upvotes: 4

gpeche
gpeche

Reputation: 22514

You are instantiating a fixed thread pool. The ExecutorService is not going to release the threads until you terminate the ExecutorService itself by calling ExecutorService.shutdown() or ExecutorService.shutdownNow().

Upvotes: 2

Related Questions