This question already has an answer here:
After executing wait(), how long does a thread wait if it does not get notified from other threads?
(1 answer)
Closed 2 years ago.
Thread t2 = new Thread();
Thread t3 = new Thread();
t1.start();
t2.start();
synchronized (t2) {
t2.wait(20000);
}
t3.start();
The above program runs without t2 waiting for 20sec. I observed that when thread object is started then it wont wait. Why is this happening?
Why is this happening?
First, let's be clear. This function call, t2.wait(20000) does not do anything to the t2 thread. In fact, it doesn't really do anything at all. All it does is not return until either one of two things happens;
Some other thread calls t2.notify(), or
20 seconds elapse.
If the call took less than 20 seconds to return, then that's probably because the t2 thread itself called t2.notify() just before it died. In most implementations of the Java standard library, the join() method is implemented by using wait() and notify() calls on the thread object.
(Note: most authors will advise you not to ever call wait() or notify() on a Thread instance precisely because of the potential for interference between your code and the library code when both call the same methods on the same instance.)
The above program runs without t2 waiting for 20sec.
As somebody else already has pointed out here, You have not provided any run() method for your t2 thread, so it's unclear why you would expect the t2 thread to "wait" or, to do anything else at all. The only thing a thread ever does is execute the code that you provide for it in a run() method.
The default Thread.run() method would call the run() method of a delegate object that you supply when you construct the threads, but your code supplies no delegate. In that case, the default run() method does nothing at all.
Use sleep to pause the thread regardless of having work to finish.
wait doesn't pause the thread, it just waits the thread to finish (and this thread already finished).
class SleepThread extends Thread {
//run method for thread
public void run() {
for(int i=1;i<5;i++) {
try {
//call sleep method of thread
Thread.sleep(20000);
}catch(InterruptedException e){
System.out.println(e);
}
//print current thread instance with loop variable
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
class Main{
public static void main(String args[]){
//create two thread instances
SleepThread thread_1 = new SleepThread();
SleepThread thread_2 = new SleepThread();
//start threads one by one
thread_1.start();
thread_2.start();
}
}
Thread sleep method in java
Related
I was trying to use java.lang.Object.wait() method and have written 3 different sample codes wherein I am getting different behavior of wait() method.
sample 1)
class Main {
public static void main(String[] args) throws InterruptedException {
ThreadB b = new ThreadB();
b.start();
Thread.sleep(10000);
synchronized (b) {
System.out.println("main thread trying to call wait() method"); //--> 3
b.wait();
System.out.println("main thread got notification");
System.out.println(b.total);
}
}
}
class ThreadB extends Thread {
int total = 0;
public void run() {
synchronized (this) {
System.out.println("child thread starts calculation"); //--> 1
for (int i=0; i<=100; i++) {
total = total + i;
}
System.out.println("child thread trying to give notification"); //--> 2
this.notify();
}
}
}
sample 2)
public class Main{
public static void main (String[] args) throws InterruptedException {
Thread t = new Thread();
t.start();
System.out.println("X"); //--> 1
synchronized(t) {
System.out.println("starting to wait"); //--> 2
t.wait(10000);
System.out.println("waiting on t"); //--> 3
}
System.out.println("Y"); //--> 4
}
}
sample 3)
public class Main{
public static void main (String[] args) throws InterruptedException {
Thread t = new Thread() {public void run()
{System.out.println("I am the second thread.");}};
t.start();
System.out.println("X"); //--> 1
synchronized(t) {
Thread.sleep(4000);
System.out.println("starting to wait"); //--> 2
t.wait(10000);
System.out.println("waiting on t"); //--> 3
}
System.out.println("Y"); //--> 4
}
}
In sample 1)
main thread goes in waiting state forever as it has called b.wait() method and there is no thread to provide notify() or notifyAll() on object b. There was child thread that has already been terminated before main thread called b.wait() method.
This output is what I expected.
In sample 2)
main thread goes in waiting state for 10 seconds (t.wait(10000);) after printing
X
starting to wait
after 10 seconds main thread executes
waiting on t
Y
This is also my expected output.
In sample 3)
main thread is NOT going in waiting state (t.wait(10000);) even though it is sure that child thread would have been terminated by the time main thread called t.wait(10000);
So why it didn't wait ? and straightaway executed
starting to wait
waiting on t
Y
This is NOT my expected output.
For the first two examples your expectations seem correct. In the third example it seems reasonable to expect that t will finish before the main thread starts waiting, and then the main thread will hang until it times out.
But as you observed, that isn't what happens.
A waiting thread doesn't stop waiting unless interrupted or notified (except for spurious wake ups, but those are the result of unpredictable race conditions; the behavior in the posted code happens reliably, so I think spurious wakeups can be excluded here).
Since there is nothing interrupting the main thread, and its wait is cut short and we've ruled out spurious wakeups, it must be receiving a notification. There is only one thing that can provide the notification, and that is the t thread.
For t to notify the main thread it must have been alive at the time that t started waiting. So what is keeping it around?
There is some not-well-known behavior that occurs when a thread terminates. The API documentation for Thread.join says:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
What happens is:
1) t prints its output and is on the way out of its run method.
2) There is a race between t and the main thread to acquire the lock on t. t needs it to call notifyAll, main needs it to enter the synchronized block. The main thread happens to grab the lock first.
3) t hangs around until it can acquire the lock.
4) The main thread enters the wait method (releasing the lock).
5) The t gets the lock and calls t.notifyAll.
5) The main thread is notified and leaves the wait method (reacquiring the lock).
Some lessons:
Don't synchronize on threads (this is a good example of why the API docs say not to do this, here you inadvertently delayed a thread from dying in a timely fashion).
If a thread isn't waiting, it doesn't get notified. If a thread starts waiting after the notification has already happened, that notification is lost.
Don't rely solely on notifications (it makes your code vulnerable to race conditions), instead use notifications along with some condition that the other thread can set. Call wait in a loop with a test condition. If you see the Thread.join source code, it is a good example, it looks something like:
while (isAlive()) {
wait(0);
}
Don't sleep while holding a lock. It makes the system less responsive for no benefit.
Be very careful about making assumptions about the order things happen in.
I am working on a small example using join method and Thread.sleep, but I am confused how the flow works.
Here is my program:
public class Test implements Runnable {
private String msg;
private int seconds;
public Reminder(int sec, String msg) {
this.sec= sec;
this.msg= msg;
}
public void run() {
try {
Thread.sleep(sec* 1000);
System.out.print(msg+ " ");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Test(1, "one"));
Thread t2 = new Thread(new Test(3, "two"));
t2.start();
t1.start();
t2.join();
t1.join();
}
}
Since I am calling t2.join(), the t2 thread should complete before t1 thread completes.
So I am expecting output as two one, but I am getting output as one two
Since I am calling t2.join(), the t2 thread should complete before t1
thread completes.
This is not correct , join will not guarantee which thread will finish first , the two threads started so no guarantee which one will finish first, join will block the main thread until the thread finishes, so basically all you are doing with join is you are blocking main thread from waiting the next thread to finish which may already finished.
if you want t1 to start after t2 finishes then you need to call start after t2 finishes and here you can use join
t2.start();
t2.join();//main thread will stop here untill t2 is finished
t1.start()
This is actually not practical since no real difference between it and doing your tasks in one thread, just the overhead of creating threads
Since I am calling t2.join(), the t2 thread should complete before t1 thread completes.
Not at all. You wait for t2 to end - but that doesn't prevent the other thread from progressing.
So only the first part of your assumption is correct. That code waits for t2 to complete. That doesn't have any effects on the "completeness" of t1.
Assume you have two runners, starting at the same point in time. You sit at the finish line, and you only observe the slower runner. Now the slower runner passes the finish line. Why would you expect the faster runner to still be running? He made it to the finish line whilst you were only looking at the slower guy!
Since I am calling t2.join(), the t2 thread should complete before t1
thread completes.
It is not the case if t1 that is started first has terminated its execution before
t2.join(); is executed.
To allow t2 to be completed before t1, start t2, invoke join() on it. Then start t1:
t2.start();
t2.join();
t1.start();
But it defeats in a some way multi threading as each thread is started only as the previous is terminated.
The threads are starting to run rightaway after you call start(). This inclused the writeln().
join() merely collects some resources from the thread, blocking until the thread is done in the process.
Join method makes the main thread wait for the other thread to complete executing before it can carry out the next code after the join function call.
This has nothing to do with the interrelationship between two or more threads that you spawn.
I am trying to achieve this: Created two different threads, one prints odd numbers, one prints even numbers. Once one thread prints a number, it has to wait for the other thread and so on, that is one-after-other.
To achieve this, i am using synchronized block along with wait() and notify().
I am creating a class whose's object will be used to pass to synchronized block in both the threads.
Here is the code:
--> This is used object which will be passed to synchronized block.
package com.vipin.multithread.variousdemos;
public class SyncObject {
public SyncObject () {
}
}
Odd Thread:
package com.vipin.multithread.variousdemos;
public class OddThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int odd_nums[] = {1,3,5,7,9};
public OddThread(SyncObject so) {
t = new Thread(this,"Odd Thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while (true) {
synchronized(so) {
System.out.println("Odd num is --->" + odd_nums[index]);
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
so.notify();
if(index>=5) {
return;
}
}
}
}
}
Even Thread: UPDATE
package com.vipin.multithread.variousdemos;
public class EvenThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int even_nums[] = {2,4,6,8,10};
public EvenThread(SyncObject so) {
t = new Thread(this, "Even thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while(true) {
synchronized(so) {
System.out.println("Even num is --->" + even_nums[index]);
so.notify(); <-- Here we are notifying.
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
//so.notify(); <-- commented out.
if(index>=5) {
break;
}
}
}
}
}
Main Application:
package com.vipin.multithread.variousdemos;
public class EvenOddDemo {
public static void main(String[] args) throws InterruptedException {
SyncObject so = new SyncObject();
OddThread ot = new OddThread(so);
EvenThread et = new EvenThread(so);
System.out.println("\nIn main thread");
Thread.sleep(1000000000);
System.out.println("Exiting main thread...");
}
}
---> As seen in the code, I am creating two threads to print even and odd numbers. I am using synchronized block, and passing object of type ==> SyncObject.
SyncObject I am passing as argument to these different threads in main.
However, this programs halts, i.e stuck only first statement gets executed, and then it waits forever:
Here is the output:
Odd num is --->1
In main thread
Even num is --->2
I am not able to understand why this program waits for ever, I am using SAME object on which we are invoking synchronized(), wait() and notify(). As per my understanding, it should work, not sure why this is not working.
Any clues as to why this is waiting forever.
UPDATE:
I did some changes in the code, UPDATE and it works fine.
I still have some doubt. Does notify() be called by the thread even if it has not locked the monitor, like in my case after i updated the code.
Sequence of events:
Odd thread gets executed first, then it calls wait() <-- it releases the monitor and now in sleep mode.
Even thread runs, prints msg, and calls notify() <-- here i am not having clear understanding.
When Even thread calls notify(), at that point it has the monitor, so when it calls notify(), does is still own the monitor?
Now, after Even thread calls notify(), then Odd thread gets notified, and hence it starts execution from the point it was sleeping. It is doing some execution and calls notify(), at that points I presume Odd thread is NOT owning the monitor, it calls notify(). So, my question is, does notify() work same whether or not the thread owns the monitor?
It is only when one do the code, one really understands this. I read book and i felt i understood everything, and seems i am back to square one!
The problem here is simply that both threads go straight into wait. Thread 1 gets so, prints value then waits. Thread 2 then gets so, prints value then waits. So both are sleeping away, since nobody is there to notify them. So, a simple fix would be to do so.notify(), right before so.wait(). Then they're not infinitely waiting.
EDIT
Odd thread starts, executes & then waits. Then even thread starts, executes, notifies & then waits. Even thread holds the lock over the monitor until it goes into wait.
When the even thread called on notify, the odd thread awakens & polls for the lock. Once the even thread goes into wait (& releases the lock), then the odd thread can obtain the lock.
If the even thread had not called on notify, then the odd thread would continue to sleep. The even thread would have gone to wait & released the lock. No thread is polling or attempting to obtain the lock, hence the program remains in the suspended state.
The documentation also provides a similar explanation. I hope that clears your doubts.
I have a simple test with thread:
package Thread;
class Sum extends Thread {
int low, up, S;
public Sum(int a, int b) {
low = a;
up = b;
S = 0;
System.out.println("This is Thread " + this.getId());
}
#Override
public void run() {
for (int i = low; i < up; i++) {
S += i;
}
System.out.println(this.getId() + ":" + S);
}
}
public class Tester {
public static void main(String agrs[]) {
Sum T1 = new Sum(1, 100);
T1.start();
Sum T2 = new Sum(10, 100);
T2.start();
System.out.println("Main process terminated");
}
}
but i don't understand when was run() method executed, it return same that:
This is Thread 8
This is Thread 9
Main process terminated
9:4905
8:4950
It's mean the run() method was executed after T1 and T2 start. I still think that when start() method was invoked the run() will be execute. Thank for advance!
When you call start() on the thread object , it invokes the run() method.
When in doubt , read the documentation: Thread#start():
causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Suggested Reading:
Why we call Thread.start() method which in turns calls run method?
Oracle tutorial
Why is run() not immediately called when start() called on a thread object in java
The start() method creates a new thread, that executes the run() method.
From Documentation:
Causes this thread to begin execution; the Java Virtual
Machine calls the run method of this thread.
When we invoke Thread.start JVM creates a new native thread and then calls Thread.run which causes this Thread to begin execution. Thread.run is invoked by JVM asynchroneously, so these 3 lines
Main process terminated
9:4905
8:4950
might appear in any order.
The thread scheduler is selecting which thread for run. It can be random selection if you are not giving any priority for the thraed.
Here the thread scheduler will select thread and it will work in two separate stack space as two independent thread process. So thread T1 starts before thread T2 and there is no sleep, no wait, no join the both will give output at same time.
for more details please visit http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#start%28%29
you can understand it more clearly if you use remaining functions of Thread like sleep(), join(), wait() etc...
Refer below code
public void acquire(){
synchronized(a){
print("acquire()");
try{
//Thread.sleep(5000);
synchronized(this){
wait(5000);
}
print("I have awoken");
print("" + a);
}catch(Exception e){
e.printStackTrace();
}
}
print("Leaving acquire()");
}
public void modify(int n){
print("Entered in modfy");
synchronized(a){
try{
//Thread.sleep(5000);
synchronized(this){
wait(5000);
}
this.a=n;
print("new value" + a);
}catch(Exception e){
e.printStackTrace();
}
}
}
And
final SynchoTest ttObj = new SynchoTest();
Thread A = new Thread(new Runnable(){
public void run() {
ttObj.acquire();
}
},"A");
Thread B = new Thread(new Runnable(){
public void run() {
ttObj.modify(97);
}
},"B");
A.start();
B.start();
As i know about wait(n), it pauses a thread until notify()/notifyAll() get called or the specified time n is over.
But...
In above methods if I directly use wait(n) as I used Thread.sleep(n),
I get runtime exception.
If I synchronize both methods instead of surrounding wait(n) with
synchronized block then I am not getting any exception but both
threads get blocked forever.
But if I do like I attached ie wait(n) surrounding with synchronized
block, it is working fine.
Please tell me why? Also tell me why is it not behaving different on positioning synchronized block if I use sleep(n) instead of wait(n)?
My question is about various result of wait(n) on various position of synchronized keyword.
#Gray
notify() or notifyAll(), and wait() must be in a synchronized block
for the object you are waiting on
explained me why I was getting run time exception by positioning synchronized block on various position.
Now please explain me, why
public void method(){
synchronized(a){
synchronized(this){
wait(n);
}
}
}
is working fine. But
public synchronized void method(){
synchronized(a){
wait(n);
}
}
is blocking my thread forever.
wait(n) and sleep(n) are completely different methods for pausing the execution of code:
wait(n) is called on an Object instance and will pause execution until the notify()/notifyAll() method is called on that instance or until the timer (the parameter) expires.
sleep(n) is called on a Thread object and essentially stops the world as far as that thread is concerned.
What your question comes down to is:
Do you want your object to act as a mutex, waiting for another piece of code to complete before continuing on it's own? Then use wait(n) with a corresponding notify()/notifyAll() in the other code.
Do you want to stop execution of the whole thread for a given timeframe? Then use Thread.sleep(n).
Maybe your code is not working because you didn't call start() on your threads? After you instantiate your threads you need to:
A.start();
B.start();
Also, you cannot do something like the following pattern. You cannot synchronize on a and then change the object of a. Well you can do it but I doubt that's what you want. Basically the a would change and someone else locking on a would lock on another object so would be able to be in the synchronized block as well. Very bad pattern.
synchronized (a) {
...
// not good
this.a = n;
}
Also, if you are not joining with the threads, then the main thread is going to continue on and not wait for A and B to finish. The JVM will wait for them to finish however since they are not daemon threads. And you have no guarantee that A will be called before B so the modify and acquire can happen in any order.
The difference between sleep(5000) and wait(5000) is that the wait can also be awoken by a call to notify() or notifyAll(), and wait() must be in a synchronized block for the object you are waiting on. synchronized also causes a memory barrier to be crossed which synchronizes the storage between multiple threads. It is more expensive because of that but in your case since you look to be sharing this.a then the memory barrier is required.
It is nothing about positioning synchronized keyword. You are facing problem since you locking other object and try to wait for another. Well #Gray has already been explained it, so not repeating it.
For your another problem, regarding why both threads are getting blocked;
Thread A: locks this [A: Runnable]
Thread A: locks a [A: Runnable]
Thread B: waiting for this [A: Runnable, B:BLOCKED]
Thread A: release this (meets wait) [A: TIMED WAITING, B:BLOCKED]
Thread B: lock this [A: TIMED WAITING, B: Runnable]
Thread B: waiting for a which is already locked by thread A [A: TIMED WAITING, B:BLOCKED]
Thread A: waiting for this which is locked by thread B [A: BLOCKED, B:BLOCKED]