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

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.

Related

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.

Sleep() method on already sleeping thread

I am working on multi threading and i got a question regard thread sleep method. when i execute sleep()(with time t1) method on already in sleeping thread(with time t2). The total sleep time is t1+t2 or t2(if t2 > t1) or t1 (if t1 > t2):
code:
my thread class:
public class SampleThread extends Thread
{
public SampleThread(String msg)
{
super(msg);
start();
}
public void run()
{
try
{
SampleThread.sleep(1000);
System.out.
println("slept for run");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.
println("extends Thread Class is exited");
}
}
my main method :
public class TestThreads {
public static void main(String[] args) {
SampleThread st = new SampleThread("Extends Thread");
some(st);
System.out.println("main thread Executed");
}
public static void some(SampleThread t2 ){
try {
t2.sleep(10000);
System.out.println("slept for some" );
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
result:
slept for run
extends Thread Class is exited
slept for some
main thread Executed
from the result i can say that because sleep time for t2.sleep(10000) is more than SampleThread.sleep(1000) run() method exited first than main method.
But my question is how much time.
Sleep is called by currently running thread, it is not called on the thread object. So your sleep inside run methods pause the Sample thread, the one in the some method pauses your main thread (the one that started the program). Two different execution processes.
The sleep method is actually a static method of the Thread (and you are even calling it as such), which should already indicate for you, that it is not 'bound' to the thread object.
You cannot call sleep twice in the same thread, as to call it has to be awaked. There is no issue of additivity or priority.
So in your code, the second thread starts, executes its run method and pause for shorter time. In the meantime, the main thread continues and pauses for a long time, while the main thread sleeps the created thread finishes its sleeping and then terminates.
You have two different threads and neither blocks each other. So the one thread will wait for 10 seconds, and the other waits for 1 second. The total time you waited depends on which thread you cared about.
Your main waited 10 seconds, it doens't care if the other thread waits for 1 second or a million seconds (if the second thread is set as a daemon thread so it doesn't block the current app).
If your main app spins up a thread that is a daemon, it won't exit until all non-daemon threads are complete. In which case your main app will do its work, and then at the very last line it'll wait until those threads are done.
You can't execute sleep on a sleeping thread because sleep is a static method and can only cause the current thread to sleep.
t2.sleep(10000); causes the main thread to sleep, not t2. It's the same as Thread.sleep(10000).

Run multiple thread at a same time then run main thread

I have to run multiple threads ||ly and after execution of all these thread main thread continue.
For eg I have one main thread and 3 sub threads, my need is
run main thread
pause main thread
run all 3 sub threads ||ly
after complition resume main thread
I create a class extends Thread and call start method of all these thread but it doesn't solve my problem.
My Code:
for (MyThread myThread : myThreads) {
myThread.start();
}
Thanks for help.
Try using Thread.join();
public class ThreadDemo implements Runnable {
public void run() {
Thread t = Thread.currentThread();
System.out.print(t.getName());
//checks if this thread is alive
System.out.println(", status = " + t.isAlive());
}
public static void main(String args[]) throws Exception {
Thread t = new Thread(new ThreadDemo());
// this will call run() function
t.start();
// waits for this thread to die
t.join();
System.out.print(t.getName());
//checks if this thread is alive
System.out.println(", status = " + t.isAlive());
}
}
Output:
Thread-0, status = true
Thread-0, status = false
Here is a stack-over-flow link for reference.
Forget 'pausing' threads. Your schedule should be
Initiate X actions on X threads
Wait for all threads to finish
Process results (if any)
So how do you wait for threads to finish? You need a synchronization mechanism. These are often OS level 'flags' called semaphores but the java library gives you a few ways of doing it. You will get a lot out of this series, particularly part 2: Thread Synchronization
CountDownLatch is much more flexible mechanism then Thread.join. It does exactly what you want. Prefer java.util.concurrent.* instead of old builtin java techniques.
Advantages:
Using CDL you deal with a single object instead of bunch of thread. That could simplify code.
It has a getCount() method which could be used to implement progress bar. With joins its much more complicated.
await(long timeout, TimeUnit unit) could be considered more comfortable than join(long millis)
You can call join() on the threads. Assuming that your threads are in myThreads and you don't want your thread to be interruptible
// ...
// create threads and start them
// ...
for (Thread t : myThreads) {
while (t.isAlive()) {
try {
t.join();
} catch (InterruptedException e) { }
}
}
If it should be interruptible:
// ...
// create threads and start them
// ...
for (Thread t : myThreads)
t.join();

Why UserThread running with ScheduleExecutorService does not get garbage collected

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.

How do I get the java.concurrency.CyclicBarrier to work as expected

I am writing code that will spawn two thread and then wait for them to sync up using the CyclicBarrier class. Problem is that the cyclic barrier isn't working as expected and the main thread doesnt wait for the individual threads to finish. Here's how my code looks:
class mythread extends Thread{
CyclicBarrier barrier;
public mythread(CyclicBarrier barrier) {
this.barrier = barrier;
}
public void run(){
barrier.await();
}
}
class MainClass{
public void spawnAndWait(){
CyclicBarrier barrier = new CyclicBarrier(2);
mythread thread1 = new mythread(barrier).start();
mythread thread2 = new mythread(barrier).start();
System.out.println("Should wait till both threads finish executing before printing this");
}
}
Any idea what I am doing wrong? Or is there a better way to write these barrier synchronization methods? Please help.
During execution of your main thread you create two other threads and tell them to wait for each other. But you wrote nothing to make your main thread to wait for them and complain it doesn't wait. Try
CyclicBarrier barrier = new CyclicBarrier(3);
mythread thread1 = new mythread(barrier).start();
mythread thread2 = new mythread(barrier).start();
barrier.await(); // now you wait for two new threads to reach the barrier.
System.out.println("Should wait till both threads finish executing before printing this");
BTW. Don't extend Thread class unless you have to. Implement Runnable and pass implementations to Thread objects. Like this:
class MyRunnable implements Runnable {
public void run(){
// code to be done in thread
}
}
Thread thread1 = new Thread(MyRunnable);
thread1.start();
EDIT
Justification for avoiding extending Thread.
The rule of thumb is as little coupling as possible. Inheritance is a very strong connection between classes. You have to inherit from Thread if you want to change some of its default behaviour (i.e. override some methods) or want to access some protected fields of class Thread. If you don't want it, you choose looser coupling - implementing Runnable and passing it as a constructor parameter to Thread instance.
Pass a Runnable instance to the constructor of your CyclicBarrier like this.
CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() {
#Override
public void run() {
System.out.println("Should wait till both threads finish executing before printing this");
}
});
new mythread(barrier).start();
new mythread(barrier).start();
You are looking for Thread.join() method...
thread1.join();
thread2.join();
System.out.println("Finished");
EDIT: because of the comments...
And if you don't want to wait forever you can also specify the maximum number of milliseconds plus nanoseconds to wait for the thread to die
Cyclic barrier is not the correct choice in this case. You must use CountDownLatch here.
I assume you have are invoking spawnAndWait method from the main method.
The reason this wont work is that the CyclicBarrier has 2 constructors. To perform post-operations you must use a 2 parameter constructor. The most important thing to remember is that the main thread will not wait by the await method; but will continue to execute. However the Thread specified in the CyclicBarrier constructor will only run when all spawned threads stop at the barrier(by the await method)

Categories