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.
Related
I have the following code:-
class ThreadB extends Thread {
int total;
#Override public void run() {
synchronized (this){
for(int i=0; i<5; i++){
total+=i;
}
}
}
}
public class Solution {
public static void main(String[] args) throws InterruptedException {
ThreadB b = new ThreadB();
b.start();
synchronized (b){
b.wait();
}
System.out.println(b.total);
}
}
Whenever I run this I get my output as 10.
If I comment the wait line I get the output as 0 always.
I am confused as to why do I get my answer as 10 always.
There are 2 threads , ThreadB and main thread so when I execute the wait method then ThreadB should be waiting as per definition and values should not get added and hence 0 should be printed by main thread then?
Every object has an intrinsic lock that threads can acquire using synchronized. A thread calls wait when there isn't anything it can do until something changes (for instance,
it might be trying to insert into a bounded queue that is currently full), it calls wait on the object whose lock it acquired with synchronized. When the main thread calls b.wait(), it means the main thread is the one that is going dormant.
When the code has wait commented out the ThreadB thread is still in the process of starting and the main thread can take the lock, then release the lock and print total before ThreadB can acquire the lock, at which time total is still 0. Technically there is a race and it's not guaranteed which thread goes first but the main thread has a good head start.
When the code uses wait then the main thread acquires the lock on ThreadB (again getting there ahead of ThreadB), then waits until it receives a notify. It happens that when a thread terminates it causes the scheduler to notify any threads in its waitset, so when threadB finishes it causes the main thread to wake up and proceed from there. Since ThreadB is done total is 10 by the time the main thread gets around to printing it.
If somehow the main thread did not get the lock before ThreadB, then (since ThreadB holds onto the lock for the whole time it is running) it couldn't acquire the lock until after ThreadB was finished. That would mean it wasn't in the waitset at the time the dying thread sent its notification, but would wait later, and there wouldn't be any notification to wake it up and it would hang.
This kind of problem - races that result in lost notifications and threads hanging - can happen when wait/notify is misused. For the right way to use wait and notify read https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html.
If you specifically want a thread to wait for another thread to finish, Thread has an instance method called join that is used for that, which the main thread would call here like
b.join();
BTW the notify-on-termination behavior is documented in the api doc for java.lang.Thread#join, it 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.
Note the warning against synchronizing on Thread objects. It doesn't play nice with JDK code like join that is locking on threads.
I am confused as to why do I get my answer as 10 always. There are 2 threads , ThreadB and main thread so when I execute the wait method then ThreadB should be waiting as per definition and values should not get added and hence 0 should be printed by main thread then?
You are getting a result because of the way Java threads terminate. When a Thread finishes, the Thread object itself is notified. So your wait() method causes the thread to wait for the termination of the background thread. The join() method is implemented by a call to wait() and you should use join() directly and not wait().
If I comment the wait line I get the output as 0 always.
If you don't have the wait() line then most likely the main thread will finish and get the value of b.total before the b thread is even started. Starting threads take a little bit of time and you need to have b.join() to make sure that you wait for the b thread to finish and to synchronize with any memory changes that the other thread has made, in this case to b.total.
If you put a sleep instead of the wait, you might still see the value of 0 even if the b thread had already set it to 10 because there is nothing that is synchronizing the memory and the b.total value of 0 might be cached. The join() method waits for the thread to finish and synchronized memory so that you can see the results of the thread.
I am trying to understand the concept of synchronized blocks in java.
As of the documents that I have read, I understood that if we acquire
a lock ( synchronized block using an instance variable ) then we
cannot acquire a synchronized lock on same object in that class. But
when I tried practically using the following snippet I found that my
understanding is going wrong.
I.e I am able to acquire lock
(synchronized block on same instance variable) in two different
methods at the same time. When the thread is started it will go to run
method and wait indefinitely and will not come out of the synchronized
block. At the same time if I call the stop method using the same
thread it goes into the synchronized block and executes notify
statement. I searched in the Java doc but I couldn't find any.
This is the code snippet:
public class MyClass extends Thread
{
private Object lock = new Object();
public void run()
{
synchronized(lock)
{
lock.wait()
}
//other code
}
public void stop()
{
synchronized(lock)
{
lock.notify()
}
//other code
}
}
Here is the code snippet of how i am managing the MyClass thread:
public class MyClassAdmin
{
MyClass _myclass;
public MyClassAdmin()
{
_myclass=new MyClass();
_myclass.start();
}
public void stop()
{
_myclass.stop();
}
public static void main(String args[])
{
MyClassAdmin _myclassAdmin=new MyClassAdmin();
_myclassAdmin.stop();
}
}
According to my understanding when the thread is started it will acquire lock on 'lock' object (synchronized block in run method of MyClass). When i call the stop method it should wait indefinitely until the run method comes out of the synchronized block (which will never happen in this case). But when i executed, call to stop method acquired lock on the 'lock' object and notified the object which resulted in shutdown of the thread.
Both of your methods use the same lock. If your MyClass thread happens to start waiting before the main thread can call the stop method, your stop method can still proceed, because the waiting thread lets go of the lock. Once a thread enters the wait method it releases the lock before it goes dormant, and doesn't re-acquire the lock until it exits the wait method.
This is the relevant API doc for Object#wait, the second paragraph covers what I described above about how wait releases the lock. Pay attention to the part where it says you have to call this method in a loop, otherwise you have an order-dependency bug that can cause the waiting thread to hang when the notification arrives in the main thread before the other thread can start waiting.
public final void wait()
throws InterruptedException
Causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object. In other
words, this method behaves exactly as if it simply performs the call
wait(0).
The current thread must own this object's monitor. The thread releases
ownership of this monitor and waits until another thread notifies
threads waiting on this object's monitor to wake up either through a
call to the notify method or the notifyAll method. The thread then
waits until it can re-obtain ownership of the monitor and resumes
execution.
As in the one argument version, interrupts and spurious wakeups are
possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
This method should only be called by a thread that is the owner of
this object's monitor. See the notify method for a description of the
ways in which a thread can become the owner of a monitor.
Understood this is a toy example, but subclassing Thread and overriding Thread methods is confusing. One of the reasons for using Runnable instead of Thread is that there's no opportunity to cause problems by mistakenly overriding Thread methods.
This is multithreaded and it may wait forever may not.
In your case you were lucky that _myclassAdmin.stop(); were executed after MyClass has started executing and executed wait();
I ran the program after changing the method stop() name to stop1() it were waiting forever.
To get consistent behavior do one thing, put a 1 sec sleep between two method call in main like:
MyClassAdmin _myclassAdmin=new MyClassAdmin();
Thread.sleep(1)
_myclassAdmin.stop();
Now, the execution will always halt.
Also, when a thread calls wait() it releases the monitor associated with it, so any other thread can aquire that lock and issue a notify() / notifyAll() to wake up waiting threads. This is expect
The following code creates a new costum Thread and waits for the thread to end and only then the main thread gets active again.
I don't quite understand how it works. Why doesn't mythread.wait(); get called immediatlly?
Why not using Thread.join() instead?
public static void main(String[] args) {
Thread mythread = new MyThread("hello");
mythread.start();
synchronized (mythread) {
try {
mythread.wait();
} catch (InterruptedException e) {
}
}
}
When a thread has finished running, it calls notifyAll() on itself. That's how Thread.join() is implemented: it waits on the thread. So, since your main thread waits on the thread, as soon as it finishes running, the main thread is notified, and can continue executing.
You're violating a documented rule: you should never wait on a Thread object. You also violate another one: wait() should always be called inside a loop checking for a condition.
The way it is working is that when myThread terminates it calls notifyAll() which wakes up your myThead.wait(). Check the java documentation for the Thread.join() method where it references its implementation.
See Java synchronization is doing auto notify on exit ? Is this expected?
Why not use join instead? I think you should. Less code you have to write. It's really not much more than what you've implemented here and other people reading your code are probably more familiar with using that call to wait on thread exit.
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.
it is an example about wait() and notify() in Java Concurrency. My theory knowledge about it doesn't explain me about this code and I cannot explain why this gives me a misunderstood result.
So, This is code to get an idea:
public class ExampleOne {
public static void main(String[] args) {
Test b = new Test();
b.start();
synchronized(b){
try{
b.wait();
} catch(InterruptedException ex){
ex.printStackTrace();
}
System.out.println(b.total);
}
}
}
class Test extends Thread {
int total;
#Override
public void run(){
synchronized(this){
for(int i =0;i<50;i++){
total+=i;
System.out.println("I am here");
}
notify();
}
}
}
The result is : 4950
So, how to understand this process (how total can be 4950)?
I understand that If I call wait() it stops the object's thread which called this method and woken up it then another thread calls notify(). Also, synchronized() block restricts threads and accept only one thread in one time.
So when thread calls notify(), it becomes non-active until other
thread calls wait()?
How wait() and notify() play it's role in this code? Also synchronized() block?
So, how many threads are created in this code?
I am confused about this. Help me to figure it out.
If I call wait() it stops the object's thread which called this method and woken up it then another thread calls notify()
Right. notify() or notifyAll() on the same object instance will awaken the thread.
So when thread calls notify(), it becomes non-active until other thread calls wait()?
No. Notify just signals a thread that is waiting on the same object. The thread that calls notify() continues running and does not release the synchronized lock that it is holding.
How wait() and notify() play it's role in this code?
Without wait/notify. the main thread would not wait for the calculation to finish so would probably print 0.
Also synchronized() block?
When you use wait() or notify() you need to be in a synchronized block. It is the monitor associated with the object instance that you are synchronized on that is being waited on and being notified. Also, the synchronized block ensures memory synchronization so the main threads sees the changes to the notify field. Each thread has a memory cache and there needs to be mechanisms in place for threads to publish their changes and see changes to fields made by other threads.
So, how many threads are created in this code?
1 thread is created by your code and the main thread is created automagically by the JVM.
It is important to realize that there is a race condition in this code. It is possible for the new thread to start up, spin through the loop, call notify and exit before the main thread actually calls wait. This is unlikely because starting a thread takes some time but it could happen. In that case, the main thread would be stuck in wait forever because there is no one there to notify it.
Couple other comments:
I recommended that you use this.notify(). It's always good to reiterate what is being notified.
As #JBNizet points out, it is better to use a private final lock object as opposed to a Thread object.
It is always recommended to define a class that implements Runnable as opposed to extending thread. Then you would do new Thread(new TestRunnable()); ....
To complement Gray's excellent answer, here's what happens:
main thread:
---------------------------------------------------->
| | |
start Test thread waits until notified wakes up and prints the result
Test thread:
------------------------>
| |
starts running notifies main thread
computes the sum
Also note that it's generally considered bad practice to call wait() and notify() on a Thread instance. A shared object, acting as a lock, should be used instead. notifyAll() should be preferred generally, or even better, a higher-level abstraction like a CountDownLatch should used.