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.
Related
For the given code snippet:
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
public void run() {
System.out.print(Thread.currentThread().getName());
}
};
Thread t1 = new Thread(r, "One ");
t1.start();
t1.sleep(2000);
Thread t2 = new Thread(r, "Two ");
t2.start();
t2.sleep(1000);
System.out.print("Main ");
}
The output is always coming as "One" "Two" "Main". Why is such behavior with threads in this code? Why always "t1" is starting first and not "t2" or main thread for that matter?
Thread.sleep() is a static method which pauses the current thread. The "current" thread here means the "thread from which the sleep() call was invoked": in this code that is always the main thread.
So your code is equivalent to, and should be written as
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
public void run() {
System.out.print(Thread.currentThread().getName());
}
};
Thread t1 = new Thread(r, "One ");
t1.start();
Thread.sleep(2000);
Thread t2 = new Thread(r, "Two ");
t2.start();
Thread.sleep(1000);
System.out.print("Main ");
}
What happens is that you start t1, pause the main thread for two seconds, then start t2, pause the main thread for another second, and then print "Main " to the console.
Technically, there is no guarantee as to how long it will be between calling t1.start() and System.out.println("One ") (from t1's runnable), and there is no guarantee as to how long it will be between calling t2.start() and System.out.println("Two "). For all practical purposes, though, these will be at most of the order of milliseconds.
However, you are guaranteed that there will be at least two seconds between calling t1.start() and t2.start(), and that there will be at least one second between calling t2.start() and System.out.println("Main ").
So for all practical purposes, you will print "One " to the console, then two seconds (plus or minus a few milliseconds, at most) later print "Two " to the console, then another second (plus or minus a few milliseconds) later print "Main ".
Any good (and reasonably configured) IDE will warn you when you refer to a static method via an object reference, as you do with t1.sleep(2000), etc. You should not ignore these warnings and should correct the code, so that it is clearer what you are doing.
here we have total three threads main, t1, t2. when execution starts all the threads in pool are executing in asynchronously, because threads of the same priority are given equal treatment by the java scheduler and, therefore they run on a first-come, first-serve basis.
use threadname.setPriority(intNum) method to assign priority, which affects the order of running threads.
I have written a program on synchronized block by locking on .class, and my program is executing thread by thread. But when i write the same code using synchronized method, the output is entirely different.
Synchronized block program given below:
public class SyncBlock {
public static void main(String[] args) {
final Thread t1 = new SimpleThread("First Thread");
final Thread t2 = new SimpleThread("Second Thread");
t1.start();
t2.start();
}
}
class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
synchronized (SyncBlock.class) {
for (int i = 0; i < 5; i++) {
System.out.println(getName() + " says " + i);
try {
sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
}
}
System.out.println(getName() + " is done.");
}
}
}
The out put is:
First Thread says 0
First Thread says 1
First Thread says 2
First Thread says 3
First Thread says 4
First Thread is done.
Second Thread says 0
Second Thread says 1
Second Thread says 2
Second Thread says 3
Second Thread says 4
Second Thread is done.
Now i am using the same program using synchronized method. But it is behaving differently. Could you please explain whether both will behave differently or is there any solution to get same output using both synchronized block and method.
Using synchronized method:
now synchronize the run method and replace this code:
public synchronized void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName() + " says " + i);
try {
sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
}
}
System.out.println(getName() + " is done.");
}
Here the output is different:
First Thread says 0
Second Thread says 0
Second Thread says 1
First Thread says 1
First Thread says 2
Second Thread says 2
First Thread says 3
Second Thread says 3
First Thread says 4
First Thread is done.
Second Thread says 4
Second Thread is done.
In your synchronized block you are locking class object which will lock execution of run method on other objects when one object has invoked it. But when you synchronized run method, you will lock object not class, so it will not block another thread to execute same method on another object. Hence both thread executes in parallel. If you want to achieve same execution as with synchronized block you can have a synchronized static method which executes steps that are in run and call it from run method
When you use : synchronized (SyncBlock.class), your code works fine because you are locking on the SyncBlock class, so other thread cannot get access to the class Object of SyncBlock until the first one releases it.
In the second case, you are locking on the current instance of SimpleThread(this), the lock will be different for both threads (you are locking on the SimpleThread instances themselves). So, the lock itself is in-effective and the JVM might as well remove the synchronization code (from jdk6 U23 - escape analysis was introduced to optimize such things)
In case of synchronized block say First thread enters first
synchronized (SyncBlock.class) {--> // here First thread takes the lock now no other thread can enter
Now when First thread reaches here
System.out.println(getName() + " is done.");
} ---> here First thread releases the lock . So this gives chance to other thread which are waiting for this lock . so in ur case Second thread takes it and then executes it and when it reaches here it will release and then again other thread can take over. Note : This behavior is not definite
Threads can execute in any manner Depends upon CPU scheduling policy
And what happens in synchronized method is as soon as one thread enters this method it will complete its task and then release the lock .After this other thread gets the chance to execute .
Also note that sleep doesnt release the LOCK . at that stage thread is in wait state
None of the other answers here is wrong, but none of them really speaks to the heart of the matter.
When you write synchronized, your code synchronizes on an Object, and the JVM guarantees that no two threads can be synchronized on the same object at the same time.
In your first example, the SimpleThread.run() method synchronizes on the unique SyncBlock class object. That prevents both threads from entering run() at the same time because they both are trying to synchronize on the same object: there is only one SyncBlock class object.
In your second example, the SimpleThread.run() method synchronizes on this. That does not prevent the two threads from entering run() at the same time because the two threads are synchronizing on two different objects: You create two instances of SimpleThread.
The program creates thread t0 which spawns thread t1 and subsequently threads t2 and t3 are created.After the execution of thread t3and the application never returns to the other threads spawned earlier(t0,t1,t2) and they are left stuck.
Why are the threads t0, t1, and t2 suspended?
public class Cult extends Thread
{
private String[] names = {"t1", "t2", "t3"};
static int count = 0;
public void run()
{
for(int i = 0; i < 100; i++)
{
if(i == 5 && count < 3)
{
Thread t = new Cult(names[count++]);
t.start();
try{
Thread.currentThread().join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName() + " ");
}
}
public static void main(String[] a`)
{
new Cult("t0").start();
}
}
The most important point you missed:
Thread.currentThread().join();
Method join in source code uses isAlive method.
public final synchronized void join(long millis)
...
if (millis == 0) {
while (isAlive()) {
wait(0);
}
...
}
It means that Thread.currentThread().join() will return only when Thread.currentThread() is dead.
But in your case it's impossible because of your running code in Thread.currentThread() has itself
this peace of code Thread.currentThread().join(). That's why after Thread 3 completion your program should hang and nothing happens thereafter.
Why are the threads t0, t1, and t2 suspended? The execution of thread t3 completes.
t3 completes because it is not trying to fork a 4th thread and therefore is not trying to join() with it's own thread. The following line will never return so t0, t1, and t2 all stop there and wait forever:
Thread.currentThread().join();
This is asking the current thread to wait for itself to finish which doesn't work. I suspect that you meant to say t.join(); which is waiting for the thread that was just forked to finish.
Here are some other thoughts about your code in no apparent order:
You should consider implements Runnable instead of extends Thread. See here: "implements Runnable" vs. "extends Thread"
You are using the shared static variable count in multiple threads without any protection of locking. The best solution is to use an AtomicInteger instead of a int. You probably don't have a problem here because each thread is modifying count and then forking another thread but if you tried to fork 2 threads, this would be a real problem because of data race conditions.
I'm not sure why you are only spawning another thread if(i == 5 && count < 3). i is only going to be 5 once in that loop. Is that really what you intended?
String[] names = {"t1", "t2", "t3"}; fields are recommended to be declared at the top of classes. Otherwise they get buried in the code and get lost.
In main you start a Cult thread and then the main thread finishes. This is unnecessary and you can just call cult.run(); in main instead and use the main thread.
Cult(String s) { super(s); } there is no point in having a constructor that calls the super constructor with the same arguments. This can be removed.
This is debatable but I tend to put main method at the top of the class and not bury it since it is the "entrance" method. Same thing with constructors. Those should be above the run() method.
catch(Exception e) {} is a really bad pattern. At the very least you should do a e.printStackTrace(); or log it somehow. Catching and just dropping exceptions hides a lot of problems. Also, catching Exception should be changed to catch(InterruptedException e). You want to restrict your catch blocks just the exceptions thrown by the block otherwise this may again hide problems in the future if you copy and paste that block somewhere.
More a good practice but never use constants like 3 that have to match another data item. In this case it would be better to use names.length which is 3. THis means that you don't need to change 2 places in the code if you want to increase the number of threads. You could also have the name be "t" + count and get rid of the names array altogether.
I have decided to face this monster called concurrency and broaden my threading knowledge, so before I read through Joshua Bloch's book, I decided to code something random to help me understand the problem I might face before reading the book, hopefully I can then come to my code and make corrections but then I landed into this pit and I am hoping someone can explain.
I have the following:
public class Arithmetic implements Runnable {
int number;
public Arithmetic(int x){
this.number = number + x;
}
#Override
public void run() {
Thread.currentThread().setName("thread-"+number +" > " + "number = "+getNumber());
System.out.println(Thread.currentThread().getName());
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = getNumber() + number;
}
}
Then a main class:
public class Main {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
for (int x=0; x<=5; x++){
Thread thread = new Thread(new Arithmetic(x));
thread.start();
}
}
}
With this I get the following as output:
run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-5 > number = 5
thread-4 > number = 4
Notice: The 5 comes before 4
But then I change my main class to:
public class Main {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
for (int x=0; x<=5; x++){
Runnable runnable = new Arithmetic(x);
runnable.run();
}
}
}
I get the output below:
run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-4 > number = 4
thread-5 > number = 5
Notice: Correct sequence
I was hoping both main(s) will produce erratic result(Like Thread implementation), then I would then use some thread safety measures like synchronised access etc. but why does the Runnable call act as if Arithmetic is thread safe?
IMO, the difference between extending Thread class and implementing Runnable is for decoupling purposes. Apologies if this is a duplicate question, I can't seem to find an answer.
Thanks in advance.
Runnables do not start new threads it is simply and interface, so this means your second piece of code runs synchronously.
Threads are new threads so you they can run in parallel, which is why the output comes out of order - the 4th thread executes slower than the 5th.
The thing is when you do
Thread t = new Thread(new Arithemetic())
t.start();
The thread t is started and it executed Arithmetic.
In your case you are calling runnable.run();, which means the current thread shall call code inside your run(). It is similar to calling any other method.
Ultimately, your current thread in itself is executing the run method 5 times
Your Runnables are all executing in the main thread (and in that code there is only the one "main" thread).
Your threads all execute separately, and java give no guarantee that once started threads will execute in any particular order.
Because Runnable itself doesn't run on a seperate thread. It is just an interface used for passing a method implementation around. One example of such is passing it to a Thread constructor (as you have done in your first example). Thus in your second example, nothing is being executed concurrently; it's just executing the run() methods one after the other.
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.