The following code gives an output of 9; But my question is which thread will call join() method. main thread calls join method than what does it mean? all the other threads should wait till main method completes? Then the output shouldn't be 9?
public class Starter extends Thread {
private int x = 2;
public static void main(String[] args) throws Exception {
new Starter().makeItSo();
}
public Starter(){
x = 5;
start();
}
public void makeItSo() throws Exception {
join();
x = x - 1;
System.out.println(x);
}
public void run() { x *= 2; }
}
That join() in makeItSo() is indeed confusing. Your code is equivalent (ignoring exceptions) to this, with the join() removed from makeItSo(), and removing start() from the Starter constructor:
Starter other_thread = new Starter();
other_thread.start(); // run gets executed in other_thread
other_thread.join(); // waits for other_thread to finish running
other_thread.makeItSo();
As in your code, it is the main thread that calls join on the secondary thread. That causes the main thread to wait for the end of run() before computing x-1 and printing it out.
So the secondary thread will have computed x*2 -> 10, and the main thread computes x - 1 -> 9 after that thanks to the join().
public class Starter extends Thread {
private int x = 2;
public static void main(String[] args) throws Exception {
System.out.println("Start of main "+Thread.currentThread().getName());
new Starter().makeItSo();
System.out.println("End of main "+Thread.currentThread().getName());
}
public Starter(){
x = 5;
System.out.println("Before starting thread " + Thread.currentThread().getName());
start();
System.out.println("After starting thread " + Thread.currentThread().getName());
}
public void makeItSo() throws Exception {
System.out.println("Before join " + Thread.currentThread().getName());
join();
System.out.println("After join " + Thread.currentThread().getName());
x = x - 1;
System.out.println(x);
System.out.println(Thread.currentThread().getName());
}
public void run() {
System.out.println("Inside running thread "+Thread.currentThread().getName() +"with value of x:" +x);
x *= 2;
}
}
OUTPUT
Start of main main
Before starting thread main
After starting thread main
Before join main
Inside running thread Thread-0with value of x:5
After join main
9
main
End of main main
Go through the code and it is pretty much self explanatory. The main thread is the one which waits at join for thread-0 spawned at the constructor to get completed. The main thread doesnt end untill the makeItSo() function call ends.
The main thread calls the join method, so it will wait for the thread spawned by Starter to stop. When you invode new Starter() it starts a thread, that finishes quickly. It's possible make is so will wait a bit until starter finishes. For a better test put a sleep in run and track the elapsed time. You will see that it wait for Starter to end.
Related
I have a custom asynchronous method and I know threads are executed randomly, but I want to execute them in order.
I want to solve the problem in the main() method.
I've tried Thread.sleep() but it's not useful.
public static void main(String[] args) throws Exception{
Monster monster = new Monster();
System.out.println(1);
monster.exe();
System.out.println(2);
monster.exe();
System.out.println(3);
monster.exe();
System.out.println(4);
}
Class Monster
class Monster {
public void exe() {
new Thread(() -> {
System.out.println("Monster...: "+ Thread.currentThread().getName());
}).start();
}
}
That's doable, but frankly pointless because such a "parallel" execution even less performant than sequential processing of these tasks.
If you are doing that just as an exercise, that's OK. Otherwise, either don't try to control the execution of these tasks or do it in a single-threaded environment.
For that, you might use method join():
public static void main(String[] args) throws InterruptedException {
Monster monster = new Monster();
System.out.println(1);
Thread thread1 = monster.exe();
thread1.join();
System.out.println(2);
Thread thread2 = monster.exe();
thread2.join();
System.out.println(3);
Thread thread3 = monster.exe();
thread3.join();
System.out.println(4);
}
Each call of join() will block the main thread until another thread (on which this method was invoked) isn't finished its job.
Note: method join() throws InterruptedException which is a checked exception and must be either handled with a try/catch or should be signified in the method declaration. I've deliberately chosen the second option in order to make the code simpler and keep focus on what it is intended to do. But you should know that it's not a good practice to add the throws clause to the declaration of the main() method.
A small change was done to the Monster class (method exe() returns a thread that has been created in order to be able to join on it).
public class Monster {
public Thread exe() {
Thread thread = new Thread(() -> {
System.out.println("Monster...: "+ Thread.currentThread().getName());
});
thread.start();
return thread;
}
}
Output
1
Monster...: Thread-0
2
Monster...: Thread-1
3
Monster...: Thread-2
4
Another way to do it is to extract the codes that you want to execute asynchronously into a separate Runnable :
Runnable newMonstorTask() {
return ()->System.out.println("Monster...: " + Thread.currentThread().getName());
}
And then use CompletableFuture to configure them to execute in order and asynchronously :
CompletableFuture.runAsync(newMonstorTask())
.thenRunAsync(newMonstorTask())
.thenRunAsync(newMonstorTask())
.thenRunAsync(newMonstorTask());
You can use CompletableFuture and then methods like thenApply().
Please look here: https://www.deadcoderising.com/java8-writing-asynchronous-code-with-completablefuture/
I am wondering what happens in the following scenario:
Two threads are created:
Thread t1 = new Thread();
Thread t2 = new Thread();
Assume these just print out a string, the threads then call the .start() method:
t1.start();
t2.start():
My question is why do these threads print in a seemingly random order each time? I know threads execute concurrently but would t1 not always finish before t2 due to the sequential execution of the main process?
Calling start() on a Thread doesn't necessarily result in the thread running immediately after. It is possible for other things to happen in between your calling start() and the first line of your thread's run() method actually being run. And even once your run() is actually running, it's also possible that other things happen before, during, or after your run() method finishes.
In your question, you said: "assume these just print out a string" – here's an implementation of run() which does that:
public void run() {
System.out.println("my name is: " + getName());
}
So it's possible that t1 starts to run first, but before it actually calls System.out.println, t2 is allowed to execute and runs to completion, then t1 is resumed.
If this kind of behavior won't work for your use case, you'll need to add some kind of concurrency protection to coordinate how and when your threads run.
UPDATE:
To illustrate the unpredictable sequence of thread execution, run this code a few times and observe the output:
public class Example {
public static void main(String[] args) {
for (int k = 0; k < 10; k++) {
new TestThread(k).start();
}
}
}
class TestThread extends Thread {
private final int k;
TestThread(int k) {
this.k = k;
}
#Override
public void run() {
System.out.print(k + " ");
}
}
Here is the output from one of my local runs:
7 0 1 5 4 6 3 2 8 9
Thread.start() doesn't guarantee execution. It will just make the Thread state runnable and hand over to the Thread Scheduler. It is the Thread Scheduler which decides which thread to run when.
If you need code to execute in a defined order on multiple threads, you need to add synchronization code between those threads.
Otherwise, the system is free to schedule execution in any order it sees fit.
I was reading Multithreading from The Complete Reference and then I was struck at this code,I am unable to understand the output of this code.Can somebody help me with this?
class NewThread implements Runnable
{
Thread t;
NewThread()
{
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start();
}
public void run()
{
try
{
for(int i = 5; i > 0; i--)
{
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
}
catch (InterruptedException e)
{
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class First
{
public static void main(String args[])
{
new NewThread();
try
{
for(int i = 5; i > 0; i--)
{
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
It produces the output:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread
Main Thread: 2
Main Thread: 1
Main thread exiting
From the main() method,the NewThread() constructor is called and then an instance of Thread class is created named "demo thread" and the first print() statement gets executed.After that the start() method is called.Is this start method not supposed to call run() method implicitly and so the child loop should be executed,but according to the output the control goes in the main loop.How can the control go to the main() loop,even if we are calling t.start()?Can somebody please clarify the code output to me please?
Once start() is called, there are now two threads running simultaneously. start() returns immediately and the main loop continues (one loop very 1000mS). But the child loop is now running at the same time also - one loop every 500mS. So, until each loop finishes, there will be two child lines printed for every main line.
Unless there's a happens-before relationship, the order of execution of independent threads is nondeterministic; this is what makes concurrency challenging. After t.start() is called, there's no relationship at all between the main thread and the thread in t, and in the unlikely case where the system is heavily loaded, one thread or the other could theoretically complete all in sequence before control returns to the other thread at all.
I am learning about MULTITHREADING in java and I want to know why in the following code, the child thread does not immediately run when the start method is executed to invoke the run method in the child thread?
Instead, after executing the start method, the main thread keeps executing its code and starts printing ".". Which it does three times and the control is taken over by the child thread. The child thread then executes its code one time and returns back to the main thread. Then main thread completes and then the child thread completes its execution as well.
I am unable to understand why this happens?
class MyThread implements Runnable {
String thrdName;
MyThread(String name) {
thrdName = name;
}
public void run() {
System.out.println(thrdName + " starting.");
for (int count = 0; count < 10; count++) {
System.out.println("In " + thrdName + ", count is " + count);
}
}
}
class UseThreads {
public static void main(String args[]) {
System.out.println("Main thread starting.");
MyThread mt = new MyThread("Child #1");
Thread newThrd = new Thread(mt);
newThrd.start();
for (int i = 0; i < 50; i++) {
System.out.print(".");
}
}
}
When you call start() on your thread, you get no guarantees on how fast it will start. This is up to the thread scheduler of your computer. If you run your code multiple times, you will likely get several different execution orders for your threads.
The call to begin a thread is asychronous. It does not wait until the thread has started running before returning; it returns essentially immediately.
You can implement that behaviour yourself, with a bit of locking, such that your main thread pauses until the thread you have begun issues a signal of some kind, to indicate it has begun execution.
I have 2 nested threads.
First thread starts multiple instances of second thread. Each second thread has to sleep for some time (5 seconds).
I want to start the first thread and return a message to user immediately, but it seems my first thread waits until all the children of second thread to finish.
How can I achieve this? Any help?
There are some common mistakes when dealing with java.lang.Thread.
Calling run on the thread instead of start. This is nothing magical about the run method.
Calling static methods on thread instances. Unfortunately this compiles. A common example is Thread.sleep. sleep is a static method and will always sleep the current thread, even if the code appears to be calling it on a different thread.
Rather than dealing with threads directly it is generally better to use a thread pool from java.util.concurrent.
What you should probably do, is create a single thread pool via Executors.newCachedThreadPool(). From your main thread submit Runnables (tasks) to the pool. Return to your main thread a list of Futures.
In Java there exists enough framework code that one rarely should need to deal with threads directly.
It may be helpful to see code. It depends on where you are putting Thread.sleep();.
Like someone else has pointed out with Threads you call start() which is a non-blocking call and actually gets the thread rolling. Calling run() will block until the run() method finishes. See the example code below;
public class Application {
public static void main(String[] args) {
FirstThread firstThread = new FirstThread();
firstThread.start();
System.out.println("Main Method ending");
}
}
public class FirstThread extends Thread {
public void run() {
for(int i = 0; i < 3; i++) {
SecondThread secondThread = new SecondThread(i);
secondThread.start();
}
System.out.println("FirstThread is finishing");
}
}
public class SecondThread extends Thread {
private int i;
public SecondThread(int i) {
this.i = i;
}
public void run() {
while(true) {
System.out.println("Second thread number " + i + " doing stuff here...");
// Do stuff here...
try {
Thread.sleep(5000);
}
catch(InterruptedException ex){
//ignore for sleeping}
}
}
}
}
Which produces the output:
Main Method ending
Second thread number 0 doing stuff here...
Second thread number 1 doing stuff here...
FirstThread is finishing
Second thread number 2 doing stuff here...
Second thread number 0 doing stuff here...
Second thread number 2 doing stuff here...
Second thread number 1 doing stuff here...
I replaced 'run' with 'start' in both first thread and second thread.
It works fine now.
Thanks to all who responded with valueble suggestions.
public class FirstThread extends Thread {
public synchronized void run() {
for(int i = 0; i < 3; i++) {
System.out.println("i="+i);
}
System.out.println("FirstThread is finishing");
}
}
public class SecondThread extends Thread {
public synchronized void run() {
for(int j = 0; j < 3; i++) {
System.out.println("j="+j);
}
System.out.println("Second Thread is finishing");
}
}
public class Application {
public static void main(String[] args) {
FirstThread firstThread = new FirstThread();
SecondThread a=new SecondThread()
firstThread.start();
a.start();
}
}
Output will be:
i=0
i=1
i=2
i=3
FirstThread is finishing
j=0
j=1
j=2
j=3
Second Thread is finishing
You can use the Synchronized keyword which will use to run one thread completely
example
public synchronized void run() //which thread to run completely
{
}