Why UserThread running with ScheduleExecutorService does not get garbage collected - java

Please help me find the reason for Thread leak in the code below. The TestThread does not get garbage collected even after run() has completed (verified from the consoled print statement) and the main method has exited (verified from print statement and profiler tool).
The TestThread, however, gets garbage collected if it is set as a Daemon Thread i.e. t.setDaemon(true). The code below is just a sample code which illustrates the problem in my application. I'm trying to use some pre-existing scheduling class (which was designed by someone else using ScheduledExecutorService). I notice that when I keep scheduling multiple Runnables with the class, the created threads never get garbage collected.
public class ThreadTest {
static void runThreadWithExecutor() {
final String name = "TestThread";
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(
new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, name);
t.setDaemon(false);
return t;
}
});
ses.schedule(new Runnable() {
#Override
public void run() {
System.out.println("entered " + name);
System.out.println("exiting " + name);
}},
2,
TimeUnit.SECONDS);
}
public static void main(String[] args) throws InterruptedException {
System.out.println("entered main");
runThreadWithExecutor();
Thread.sleep(5000);
System.out.println("exiting main");
}
}

This is due to the fact that you are not calling shutdown() on your executor service after you have scheduled your last job:
ses.schedule(...);
// this stops any management threads but existing jobs will still run
ses.shutdown();
I just added the shutdown() call to your code and it exits fine. This is true of all ExecutorServices. Without the shutdown the thread pool continues to wait for more jobs to be submitted and is never GC'd.
See #John's answer below for more details.

#Gray is correct with his assessment I just figure I add the why he is correct. The ExecutorService is a thread-pool which will reuse the threads.
Unlike new Thread(runnable).start(); when the run method completes the thread completes and will then be GC'd. When an Executor Runnable completes the thread will sit there and wait for another runnable task to be submitted and used. So by shutting down you are telling the executor to end all of the Threads in the thread pool.
To answer your last part. Setting it to daemon works only because there are no other (non-daemon) threads running. If your application started some other non daemon thread the Executor thread's will continue. Remember a daemon thread will be killed when only daemon threads are running.

Related

Java Garbage Collection for Threads

How exactly does Java's garbage collection handle threads?
To clarify, I have a peer to peer network I'm writing in Java, and if a peer is determined to be acting maliciously or is rejected from the routing tables, I remove all references to the Peer object, which extends a thread.
Would I be correct in assuming that even though I deleted all references to the instance, the thread for that instance, and therefore the instance, would not be removed by the garbage collector?
No. It will not be collected or stopped while it is running.
You should stop your thread from within the thread, for example by using using the command return;.
Here is an experiment:
public class Main {
public static void main(String[] args) {
Runnable r = new Runnable(){
public void run() {
for (int i=0; i < 10; i++) {
System.out.println("Thread is running");
}
return;
}
};
Thread t=new Thread(r);
t.start();
t=null;
System.out.println("App finished");
}
}
Here is the result:
App finished
Thread is running
Thread is running
Thread is running
Thread is running
Thread is running
Thread is running
Thread is running
Thread is running
Thread is running
Thread is running
So, the thread was not stopped or collected even after the main thread set the reference to null and stopped working.

why does the main thread wait

In the below code, why does the main thread wait until the child thread is finished.
Driver.java
public class Driver {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new ThreadRunner());
t.start();
}
}
ThreadRunner.java
public class ThreadRunner implements Runnable {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Child thread" + i);
}
}
}
Here in the Driver class after calling 't.start()' shouldn't the program quit? I'm not using join but still the main thread waits until the newly spun 'ThreadRunner' run is running. Is it because in java the main thread (which is started by main method) always waits until all the threads are shut?
The main thread exits immediately after having started the other thread, but the Java program as a whole continues running as long as there are non-daemon threads alive (and unless you specifically request it, new threads will be non-daemon).
Making the thread a daemon thread is easy: simply call t.setDaemon(true); before starting it.
The main thread doesn't actually wait. The main thread completes. The program does not quit because you create a Thread that is non-daemon. The JVM will shut down when only daemon threads remain.
you can add 'System.out.println("main thread");' below 't.start()'
then you can see main thread is the first.

Thread Join Method. Can main thread complete before other Threads?

I know how the thread join method works, but i have a sample question. Please see the example code below
public class RunnableJob implements Runnable{
#Override
public void run(){
Thread currentThread = Thread.currentThread();
System.out.println("Runnable job is run by" + currentThread.getName());
try{
Thread.sleep(1000);
}
catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
public class ThreadExample{
public static void main(String[] args) throws InterruptedException{
RunnableJob runnableJob = new RunnableJob();
Thread thread1 = new Thread(runnableJob,"T1");
Thread thread2 = new Thread(runnableJob,"T2");
Thread thread3 = new Thread(runnableJob,"T3");
Thread thread4 = new Thread(runnableJob,"T4");
thread1.start();
thread1.join();
thread2.start();
thread2.join();
thread3.start();
thread3.join();
thread4.start();
thread4.join();
Thread thread5 = new Thread(runnableJob,"T5");
Thread thread6 = new Thread(runnableJob,"T6");
Thread thread7 = new Thread(runnableJob,"T7");
Thread thread8 = new Thread(runnableJob,"T8");
thread5.start();
thread6.start();
thread7.start();
thread8.start();
}
}
I know that, T1,T2,T3,T4 will block the main thread, before they complete. But is it possible that before T5,T6,T7,T8 actually start running, the main thread completes and T5..T8, remain in runnable state only. If this is possible, how can i produce the same?
Thanks.
The term you are looking for to answer your question is "daemon" threads. As long as there are non-daemon threads running, the application will not terminate and those threads will be able to run to a terminated state.
In your case, therefore, T5...T8 will run and complete as they are non-daemon threads †.
From the documentation for Thread:
When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:
•The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
•All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method
† In fact the original single non-daemon thread started by the JVM may enter the terminated state before T5...T8 do. That will not stop T5...T8 running to completion in this case.

How can I tell that threads in ThreadPoolExecutor are done?

I am writing code where I need to make sure that no threads are currently running in a thread pool before I commit results (to avoid losing data I should have put in the commit). For that, I'm using:
while (_executor.getActiveCount() > 0)
{
try
{
Thread.sleep(10); // milliseconds
}
catch (InterruptedException e)
{
// OK do nothing
}
}
But a colleague pointed out in review that the doc for getActiveCount states:
Returns the approximate number of threads that are actively
executing tasks.
So, is there a risk I would get out of the while loop while there are still active threads in the pool? If so, what would be the correct way to wait for all my worker threads to be done?
Edit: To give some more context: this is an online system, where the task that contains the executor service is left running indefinitely. Work comes in via a messaging system, is put on a thread in the executor, which doesn't need any synchronization, and works come out into another queue for the messaging system. I don't want to kill the executor to wait for completion of tasks.
You might want to consider using a CompletionService (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CompletionService.html).
A CompletionService wraps an ExecutorService and returns a Future when tasks are submitted. By maintaining a list of these Futures, you can see if the jobs that you're waiting on have completed. It also has the additional advantage that you can have others use the same ExecutorService since you have some means of accounting,
_executor.awaitTermination(); should do the job. Now, it won't actually wait for the threads to shutdown, but rather it would wait for all available tasks to terminate.
You could also provide keepAliveTime to a thread pool constructor to instantly terminate idle threads:
ExecutorService executor = new ThreadPoolExecutor(0, 10, 0L /* keepAlive */,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
To notify a thread that it should clean up and terminate, use the interrupt method.
t.interrupt();
and it is good to print or have log of your errors from catch block.
When tasks are submitted to the executor, they return Futures, which indicate when they complete. That is the preferred mechanism to use.
You can use JDK ExecutorService shutdown/awaitTermination.
Use case: need to cleanup thread-locals in pool threads upon their completion and this cleanup can take long (e.g. connection close). Only after that the main thread can continue.
A worker thread can register itself in some collection. For that override start() and run() and pass a custom thread factory to ThreadPoolExecutor:
class MyThreadFactory implements ThreadFactory {
#Override
public Thread newThread(final Runnable r) {
return new MyThread(r);
}
...
class Some {
void waitAllThreads() {
Thread worker;
while ((worker = workerThreads.poll()) != null) {
worker.join();
}
}
...
class MyThread extends Thread {
#Override
public synchronized void start() {
if (getState() == State.NEW) {
some.workerThreads.offer(this);
}
super.start();
}
#Override
public void run() {
try {
super.run();
} finally {
some.workerThreads.remove(this);
}
}
...

Java ExecutorService pause/resume a specific thread

Is there a way to use ExecutorService to pause/resume a specific thread?
private static ExecutorService threadpool = Executors.newFixedThreadPool(5);
Imagine that I want to stop the thread which as the id=0 (assuming that to each one is assigned an incremental id until the size of the threadpool is reached).
After a while, by pressing a button let's say, I want to resume that specific thread and leave all the other threads with their current status, which can be paused or resumed.
I have found on Java documentation a uncompleted version of PausableThreadPoolExecutor. But it doesn't suit what I need because it resume all the threads in the pool.
If there's no way to do it with the default implementation of the ExecutorService can anyone point me to a Java implementation for this problem?
You are on the wrong track. The thread pool owns the threads and by sharing them with your code could mess things up.
You should focus on making your tasks (passed to the threads cancellable/interruptable) and not interact with the threads owned by the pool directly.
Additionally you would not know what job is being executed at the time you try to interrupt the thread, so I can't see why you would be interested in doing this
Update:
The proper way to cancel your task submitted in the thread pool is via the Future for the task returned by the executor.
1)This way you know for sure that the task you actually aim at is attempted to be cancelled
2)If your tasks are already designed to be cancellable then your are half way there
3) Do not use a flag to indicate cancellation but use Thread.currentThread().interrupt() instead
Update:
public class InterruptableTasks {
private static class InterruptableTask implements Runnable{
Object o = new Object();
private volatile boolean suspended = false;
public void suspend(){
suspended = true;
}
public void resume(){
suspended = false;
synchronized (o) {
o.notifyAll();
}
}
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
if(!suspended){
//Do work here
}
else{
//Has been suspended
try {
while(suspended){
synchronized(o){
o.wait();
}
}
}
catch (InterruptedException e) {
}
}
}
System.out.println("Cancelled");
}
}
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
ExecutorService threadPool = Executors.newCachedThreadPool();
InterruptableTask task = new InterruptableTask();
Map<Integer, InterruptableTask> tasks = new HashMap<Integer, InterruptableTask>();
tasks.put(1, task);
//add the tasks and their ids
Future<?> f = threadPool.submit(task);
TimeUnit.SECONDS.sleep(2);
InterruptableTask theTask = tasks.get(1);//get task by id
theTask.suspend();
TimeUnit.SECONDS.sleep(2);
theTask.resume();
TimeUnit.SECONDS.sleep(4);
threadPool.shutdownNow();
}
Suggestion: Similarly to/instead of the flags you're using, create a semaphore with 1 permit (new Semaphore(1)) for each task you need to pause/unpause. At the beginning of the task's working cycle put a code like this:
semaphore.acquire();
semaphore.release();
This causes the task to acquire a semaphore permit and immediately release it. Now if you want to pause the thread (a button is pressed, for example), call semaphore.acquire() from another thread. Since the semaphore has 0 permits now, your working thread will pause at the beginning of the next cycle and wait until you call semaphore.release() from the other thread.
(The acquire() method throws InterruptedException, if your working thread gets interrupted while waiting. There is another method acquireUninterruptibly(), which also tries to acquire a permit, but doesn't get interrupted.)
One scenario could be, one wants to simulate a number of devices. Devices have functions. Altogether this collection of devices runs concurrently. And now if a thread represents a device ( or one thread for one function of a device ), one might want to control the life cycle of the device like start(), shutdown(), resume()

Categories