class TestJoinMethod3 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestJoinMethod3 t1=new TestJoinMethod3();
TestJoinMethod3 t2=new TestJoinMethod3();
System.out.println("Name of t1:"+t1.getName());
System.out.println("Name of t2:"+t2.getName());
System.out.println("id of t1:"+t1.getId());
t1.start();
t2.start();
t1.setName("Hello");
System.out.println("After changing name of t1:"+t1.getName());
}
}
i got this out put
Output:
Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running...
After changling name of t1:Hello
running...
but according to my debugging i expected this one
Output:
Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running...
running...
After changling name of t1:Hello
What mistake i have done in my debugging?
As mentioned here, Threads are meant for executing code/instructions separately and usually up-to the mercy of Scheduler, an Operating System component.
When you say t1.start(), you're asking for a new thread to be started, but it's not guaranteed to run immediately. It goes in to a state called Runnable which makes them eligible for scheduling. Once the Scheduler picks these Runnable threads and allocates CPU to them, then they're actually in Running state. This is actually the time when your code inside run() is executed.
In java, your main thread (in your case the thread executing your main()) will not wait until all the threads it spawned are done executing their code. All threads are usually executed in a call-stack separate from your main method call-stack so the control immediately comes back to main() for executing the remaining the code (in your case , sys-outs). It's possible that by the time, main() ended, Thread t2 is not picked by the Scheduler, that's why you're not seeing 2 Running statements. Perhaps, if you try several times, then you might 2 statements but it's not guaranteed. Like I said earlier, it's up to the scheduler.
Perhaps, if you try to write them to a file, then you might see 2 Running statements (or) you can try using a thread-pool from Executors class which will not shutdown until you explicitly call shutdown(). That another way to experiment with threads without having to create them by ourselves.
Here's an image to help you understand the flow. Every method call becomes a new stack frame (even calls to constructors but I removed them for brevity) in a call-stack executed by a thread. As and when a method is completed, stack frames are removed and finally comes back to main().
PS: Above image is an approximation, it's not an accurate representation of how JVM manages threads.
To make the main thread wait for the threads to run to completion, you can use a lot of thread co-ordination constructs like join(), wait() & notify(), Semaphores & Cyclic Barriers.
join() is the simplest of all but it doesn't scale well when you're dealing with lot of threads.
So if you want your main thread to wait until t1 and t2 are done, you need to explicitly say so by doing something like this
t1.join() // blocks the main method thread until t1 is done
t2.join() // block the main method thread until t2 is done
If you're using join(), then you need to handle InterruptedException. join() also has overloaded method that waits for a specific time instead of waiting indefinitely like the no-arg version.
Threads run independently, you need to synchronize them to get the desired output. What you can do is:
class TestJoinMethod3 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestJoinMethod3 t1=new TestJoinMethod3();
TestJoinMethod3 t2=new TestJoinMethod3();
System.out.println("Name of t1:"+t1.getName());
System.out.println("Name of t2:"+t2.getName());
System.out.println("id of t1:"+t1.getId());
t1.start();
t2.start();
try{
t1.join();
t2.join();
}catch(InterruptedException e){
System.out.println("Interrupted");
}
t1.setName("Hello");
System.out.println("After changing name of t1:"+t1.getName());
}
}
Related
Normal java threads, not daemon threads, seem to execute till end, then main thread finishes, like this:
public static void main(String[] args) {
for(int i = 0; i < 3; ++i){
new Thread(new Runnable(){
#Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("Does this still print?");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
// Java normal threads don't have to call join, they'll still wait to finish.
System.out.println("Main thread start");
}
It will print:
Main thread start
i = 2
i = 0
i = 1
Does this still print?
Does this still print?
Does this still print?
What I saw here is, Java normal threads don't have to call join() and their holder still wait for them to finish. Not sure if my program is too simple to encounter any undefined behavior, could you kindly give some hints when should we use join()?
Thanks.
t.join() does not do anything to thread t in Java. All it does is not return until thread t has finished.
A Java program's main() thread does not wait for any other thread to finish after main() returns. It just ends, and any other non-daemon threads keep running.
Java is not like Go. In Go the program continues only as long as the main thread is alive, in Java any living nondaemon thread keeps the jvm around. In your code the main thread kicks off other threads and then dies. The new threads run to completion even though the main thread is long gone.
For "undefined behavior" I'm guessing you mean data races, or memory visibility issues, where you can't rely on one thing happening before another (for races) or on a value being visible across threads (for vidibility). Calling join does create a happens-before edge. So does calling println (since it acquires a lock). The Java language spec has a list of things that create a happens-before edge.
Calling get on a Future blocks until the future is done similar to how calling join on a Thread blocks until the thread is finished. If you use higher level constructs than just threads, whether it's executor services, CompletableFuture, reactive libraries, actor systems, or other concurrency models, then those are to different extents shielding you from the Thread api and you don't need join so much.
I wrote a following program and from my understanding it should not print
'Didn't hang, it should've. as shouldHang method is static synchronized and i have already taken a class level lock.
I am unable to understand this behavior. Can some one help me on this,
public class Test1 {
synchronized static public void shouldHang() {
System.out.println("Didn't hang, it should've.");
}
static public void main(String args[]) {
Test1 test = new Test1();
synchronized (test.getClass()) {
new Thread(new trylock()).start();
}
}
}
class trylock implements Runnable {
public void run() {
Test1.shouldHang();
}
}
Why shouldn't it print it? You have a single thread invoking a single synchronized method. The main thread has finished executing (and thus released the lock) when the method is invoked. Starting a thread just starts it and returns immediately, so the sequence of events is:
main thread acquires the lock
main thread starts another thread
main thread releases the lock (and stops running)
second thread acquires the lock
second thread prints
second thread releases the lock (and stops running)
The second thread might try acquiring the lock while the main thread still has it, but that doesn't change anything: the main thread releases it, and thus makes it available for the second thread.
Your main thread doesn't hold the lock for the whole lifetime of the try-lock thread. You need to ask the main thread to wait. Then you'll have a deadlock. Is that what you want?
synchronized (test.getClass()) {
Thread t = new Thread(new trylock());
t.start();
t.join(); // Now the thread hang, but of course this will only deadlock your program.
}
Thread.start starts the given thread and then immediately returns; it does not wait for the newly started thread to finish.
In this case, the new thread starts and is blocked, as you say; but immediately afterwards, the main thread returns from the start() method and the synchronized block competes, unblocking the new thread and letting it print its message.
Why shouldn't that be printed?. Your main thread takes the lock only to create and start the second thread and then releases the lock. Then the second thread takes the lock and executes the method. Note that the second thread might indeed be waiting for a "very trivial" time, hence you are not seeing it.
If you really want to see the behavior of synchronized here, add a small sleep of 5 seconds after your thread starting block.
I wanted to know how does thread's join() method works. I was assuming that when we give t.join() after t.start(), then the rest of the threads may be main will execute after Thread t has completed its process. When I execute the following code :
public class Run extends Thread {
void go(){
System.out.println(isAlive());
}
public static void main(String[] args) throws Exception{
Thread t=new Run();
t.start();
//t.join();
((Run)t).go();
}
}
I could get either true or false in output. If t.start() executes before ((Run)t).go() , then output will be true or else false But I want to get output as always true. So I uncomment the line t.join(), so that main thread's ((Run)t).go() gets executes at the end. But now I always get the output as false. I expected it to be true. can any one clear away my confusions? I know I have not included Thread's run() method.
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join--
Waits for this thread to die.
Your program has two threads: the Main thread and the instance of Run. When the main thread calls t.join(), it will wait until t dies, then proceed. So after Thread.join() returns, the thread will, by definition, be dead.
But I want to get output as always true. So I uncomment the line t.join(), so that main thread's ((Run)t).go() gets executes at the end.
If you want the result to be true, you need to ensure that that the thread is alive when you check; the most straightforward way is to check from the running thread (i.e., from the thread's target run() method), but if you need to check from another thread, you'd need to create a synchronization mechanism between the threads, like a CountdownLatch. Then, the thread would wait to die until the main thread has checked its status.
However, all this seems very contrived. The join() method waits for another thread to die. If you check that thread after join() has successfully completed, of course you will see that it is not alive.
I wanted to know how does thread's join() method works.
How it works? or what it does?
What it does is, t.join() waits until thread t is dead. (I.e., you call it, and it doesn't return until t is dead).
How it works is, it sits in a loop, testing the status of the thread and calling t.wait() if the thread is not dead yet. One of the last things the thread does as it dies is to change its state and then call t.notifyAll().
join()- waits for the thread to die.enter code here
class JoinDemo{
Thread thread1 = new Thread(
new Runnable() {
public void run () {
//your code logic goes here
}
}
);
Thread thread2 = new Thread(
new Runnable() {
public void run () {
//your code logic goes here
}
}
);
thread1.start(); //line1
thread1.join(); //line2
thread2.start();//line3
}
Here in this example there are 3 threads, main,thread1,thread2. Currently running thread ie. main will wait for the thread1 to die.After thread1 dies, it will contniue to execute thread2. So main thread will come to line3 only after thread1 dies.
how to start and run a new, most important, thread by stopping current processing thread in JAVA. i.e. a current thread's processing is going on and we want to stop or halt this thread for some time and execute a new thread.
There is no such fine grain control over threads in Java. You normally try to stay away from thread priorities, as it generates brittle system. But if you absolutely must, you can change a threads priority and it will be taken into consideration by most systems.
Thread.currentThread().setPriority(Thread.MAX_PRIORITY-1); // make it important
You can pause other threads only if they do support this. But keep in mind that a paused thread still does occupy all memory and resources. The work needed to pause and resume a thread might not be justified by the gains. (In this regard priorities are better).
To pause a thread you can for example use a lock which you aquire in the worker thread. Whenever it is locked (by a more important thread) it will make the worker thread pause (with no CPU usage).
class WorkerThread {
Semaphore sem;
void checkForPause() throws InterruptedExec{
synchronized(sem) { // make sure unpauseThread() cant release it
sem.aquire(); // will block when pauseThread aquired one
sem.release();
}
}
void pauseThread() {
sem.aquire();
}
void unpauseThread() {
synchronized(sem) { sem.release(); } // only release after checkForPause()
}
work run() {
while(true) { // do something in a loop
checkForPause();
// do actual work in small steps
}
}
}
Now the WorkerThread instance can be controled with pauseThread() and unpauseThread().
BTW: in older Java there was Thread#suspend() and Thread#resume() but it should not be used in modern programs. In the deprecation notice is some alternative code.
You need to use Thread's Class join() method.
Let say if you have 2 threads T1 and T2.
When you call T1.start() , T1.join() and call T2.start() then T1 will wait until T2 finishes it work and after that T1 is going to execute.
Please go through the below link for more details.
Thread join() method
The question is, is it possible to have an external thread or do they have to be internal to the class they run in. If so could someone show me how. (external thread)
A thread, or, more precisely, a thread of execution is something, and the class Thread is something closely related but different, and it seems that you are mixing up these two concepts.
You can think of a thread of execution as a machine that will execute operations sequentially. One way to define and run such a machine is to write a class MyClass with a main() method and call java MyClass.
Another way is to create a new instance of the Thread class and call its method start(). This will create a new thread of execution which will run the code that is in the run() method of the Thread class, which does nothing by default. For this to be useful, you usually override the run method, which is what I think you are calling a thread internal to the class...:
class MyThread extends Thread {
#Override public void run() {
// ... some code ...
}
}
// ...
final Thread t = new MyThread();
t.start();
In this example, after the run() method of the class MyThread returns, the thread of execution associated to that instance of MyThread will terminate (just like when your single-threaded program returns from -- or reaches the end of -- your main() method).
Another possibility is to pass the Thread an instance of a Runnable. Then you separate the 2 concepts: the thread of execution, which is represented by an instance of Thread, will execute the code in the instance of Runnable:
class MyRunnable implements Runnable {
#Override public void run {
// this code will get executed by a thread
}
}
// ...
final MyRunnable r = new MyRunnable();
final Thread t = new Thread(t);
t.start();
This maybe closer to what you call an external thread, although this nomenclature is highly unconventional.
So, you see that there are 2 different, but closely related, concepts here.
Now, in Java you have a way to create a thread of execution that will be waiting for you to give it some code to execute. After it is created, it goes to a pool, and sits there. You submit some code for it to run, and when it finishes, instead of terminating, the thread of execution keeps alive and goes back to that pool. Maybe this is what you are looking for.
To do it, you usually use an ExecutorService. For example:
class MyMainClass {
private static final ExecutorService es = Executors.newFixedThreadPool(10);
public static void main(String... args) {
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
es.submit(new MyRunnable());
}
}
In this example, the pool contains 10 threads of execution. You can submit any amount of instances of Runnable for it, and it will distribute them among the 10 threads. Each call to submit(...) on the ExecutorService returns an instance of Future, which you can use to know if the thread of execution that was running your Runnable did already finish, and if it finished successfully or due to an uncaught exception.
I suggest that you take a look at the javadocs for all the classes I mentioned here: Thread, Runnable, ExecutorService, Executors and Future. There's a lot to learn from that documentation!
As a final note, remember that if you start playing with threads and ExecutorServices, you will get all kinds of headache. You will have to think about situations in which the execution cannot proceed (deadlocks, livelocks), about operations that need to be atomic (ie, incrementing a variable from different threads), memory visibility (ie, if you change the value of a field without "taking care", it can happen that other threads will never notice the change to that field!). Also remember that the JVM won't die until every last non-daemon thread finishes; in other words, the example above will never terminate, even if all the submitted Runnables finish, because the threads of execution in the ExecutorService are still alive!