Code:
//List all threads:
Set<Thread> runningThreads = Thread.getAllStackTraces().keySet();
System.out.println(runningThreads.toString());
//Thread creation:
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(this);
//Thread termination:
executorService.shutdownNow();
//List all threads:
Set<Thread> runningThreads = Thread.getAllStackTraces().keySet();
System.out.println(runningThreads.toString());
I would expect the list that gets printed out to be exactly the same both times but what I'm getting is a print out of the thread that was created included in the results
How do I completely destroy a thread so that it's nowhere to be found?
shutdownNow() attempts to stop the running thread, but as its API documentation says:
This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.
So the thread may still be running when the code after the call to shutdownNow() returns. Note also that you need to make sure that the task running in the thread actually terminates; shutdownNow() is not going to kill the thread, it will just try to interrupt it.
As the documentation says, call executorService.awaitTermination(...) after calling shutdownNow() to wait until the thread has stopped.
Related
if I instantiate an Executor like so:
private final Executor executor = Executors.newFixedThreadPool(2);
And then execute some code as below:
executor.execute(() -> {
doSomeThingHere();
});
What happens to the threadpool does it get destroyed after the code executes? Executor does not have any shutdown method? I am experiencing a build up of threads in my application every time I run through the process of the app. This may not be the cause but I want to understand this and rule it out. At the moment every time I want to run code on the background I instantiate a new executor in this way.
Use ExecutorService instead of Executor since newFixedThreadPool() returns an ExecutorService and that has a shutdown method.
If the executor is created with a ThreadFactory that creates daemon threads (see setDaemon), and there are no other non-daemon threads running, like the main thread or the EDT, the virtual machine will be terminated (stopping all threads)
This question already has answers here:
ExecutorService, how to wait for all tasks to finish
(16 answers)
Closed 5 years ago.
I am in the process of writing a code where whenever a folder is encountered it is supposed to start a new thread. The code looks like,
p
ublic void diff(File x,File y){
ThreadPoolExecutor executor=new ThreadPoolExecutor(10,30,2000,unit,BlockingQueue<Runnable> queue)
if(x.isDirecotry && y.isDirectory){
Runnable thread=new DThread(x,y);
Future<?> result=executor.submit(thread);
if(result.isDone()){
LOGGER.debug(thread.toString()+"has completed");
}
I am using ThreadPoolExecutor for this purpose. If I shutdown the ThreadPoolExecutor then it will not take up any new Threads. But there is a possibility of new threads starting after starting. If I do not shutdown the ThreadPoolExecutor then all the threads are executed but in the end the JVM is not terminating.
Please help how can I shutdown the threadPool only when all the threads are executed so that the JVM gets terminated. Also suggest if there is better way of implemention of thread pool.I want to use thread pool so that I can use threads from the pool instead of creating new thread everytime.
The things that you are submitting should not be threads (subtypes of Thread). They should be simple tasks: implementations of Runnable or Callable.
The way to shutdown the executor is to call shutdown() or shutdownNow() on it. The javadoc summary says:
void shutdown() -
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
List<Runnable> shutdownNow() - Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
The latter attempts to stop the tasks by interrupting them. However, if the task code does not check for interrupts, it will run to completion. (It also stops accepting new tasks.)
It sounds like shutdown() does what you want to do.
The problem lies in the fact where should I place the shutdown method.
You call it when you want to start shutting down.
Because there is a possibility that new threads may be coming after shutdown is being called.
Stop calling them threads. They are tasks.
Any tasks that are submitted after shutdown() has been called are rejected.
My question is how can I check whether all the tasks have finished executing and only then call shutdown. If I call with the initiation of each task then it will not allow new tasks later on.
The correct time to call shutdown() is when your application has finished submitting tasks to the executor.
Maybe your conceptual problem is the scoping of the executor service. Your example code seems to show that each call to diff is creating a new service object. That means that you would have lots of independent thread pools ... and no reuse of threads. What you should really do is to create a "global" thread pool and have multiple calls to diff submit tasks to the same pool.
I need to do something like this:
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executor);
int i = 0;
while (i < 40) {
completionService.submit(getTask());
i++;
}
executor.shutdown();
System.out.println("SHUTDOWN");
But after calling shutdown on executor object completionService still execute tasks.
How can I make it stop?
Is there are any way to stop ExecutorService but wait for the completion of currently executing tasks?
The ExecutorService will carry on executing tasks already submitted but will not allow further tasks to be submitted, from the documentation
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
emphasis mine
So you have already submitted 40 tasks, these will be executed before shutdown.
If you want to force shutdown. You can use shutdownNow:
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
emphasis mine
Which will abandon scheduled tasks, as you want.
N.B.: Stopping tasks in progress is another issue entirely.
Use shutdownNow() which will try to stop already executing task. Read this https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()
The shutdown of already executing task is an attempt only but will not be guaranteed to stop.
The shutdown() method only stops taking new tasks but already executing task will continue to execute.
UPDATE for the "Is there are any way to stop ExecutorService but waiting for completion currently executed tasks?"
One option I can think of is this -
The completionService.submit(getTask()); return object of type Future. You can write code to check if the task isDone(). After calling shutdownNow() you can check the tasks in a loop for isDone(). You need to store the tasks in list when returned by submit method.
I create the ExecutorService on Thread A, then Thread B calls shutdown() and awaitTermination() on the ExecutorService.
Assuming all tasks have been already been submitted prior to Thread B's creation, and no new tasks will be submitted, is there any danger?
I'm guessing it's fine, but it never hurts to ask.
As you guessed it is absolutely fine to call ExecutorService shutdown() and awaitTermination(..) on the ExecutorService from Thread B.
Infact in the usual usage of ExecutorService, one thread takes care of adding all the thread tasks to the executorservice and then the same thread initiates a graceful shutdown() and then awaitTermination(..). So in your case you are just creating ThreadB to do your shutdown tasks.
Ideally it would be better to not submit your ThreadB to the same ExecutorService which it would try to shutdown() which I believe you would have taken into consideration.
I want to close all thread which I started previously.
Thread.currentThread() gives me current thread, but what about others? How can I get them?
I think Thread.activeCount() returns the count of active threads in thread's thread group, but I does not use ThreadGroup,
I just started threads using Thread thread = new Thread(new MyRunnable()).
So how can I achieve this?
thanks in advance...
You can use an ExecutorService instead which combines a thread pool with a queue of tasks.
ExecutorService service = Executors.newCachedThreadPool();
// or
ExecutorService service = Executors.newFixedThreadPool(THREADS);
// submit as many tasks as you want.
// tasks must honour interrupts to be stopped externally.
Future future = service.submit(new MyRunnable());
// to cancel an individual task
future.cancel(true);
// when finished shutdown
service.shutdown();
You can simply keep references to all the threads somewhere (like a list) and then use the references later.
List<Thread> appThreads = new ArrayList<Thread>();
Every time you start a thread:
Thread thread = new Thread(new MyRunnable());
appThreads.add(thread);
Then when you want to signal termination (not via stop I hope :D) you have easy access to the threads you created.
You can alternatively use an ExecutorService and call shutdown when you no longer need it:
ExecutorService exec = Executors.newFixedThreadPool(10);
...
exec.submit(new MyRunnable());
...
exec.shutdown();
This is better because you shouldn't really create a new thread for each task you want to execute, unless it's long running I/O or something similar.
If you wish to keep using the Thread object directly and not using ready-to-use thread services from java.util.concurrent you should keep a references to all started thread (for example, put them in a List) and when wish to to close them, or interrupt them to stop, loop over the List.