Threads synchronization - java

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.

Related

If java normal threads don't call "join", does it lead to unknown behavior before finish?

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.

Java: Does this pause the thread correctly?

I am curious whether it is possible to pause a thread t in Java and allow another thread to resume it later, by having t run the following pause code:
while(true) {
try {
synchronized(t) {
t.wait();
}
} catch(InterruptedException e) {
break;
}
}
And then resuming the thread t by calling .interrupt() on it. However, I have read about spurious wake-ups, and so I wondered whether my code can fail, in the sense of exiting the while-loop despite no other thread calling .interrupt() on it. While this answer and this answer state that there are no spurious interrupts, and hence my code will never fail, the Java docs does not seem to address this. My question probably boils down to whether InterruptedException is ever thrown without the thread being interrupted by .interrupt(). Is there any official source or documentation that confirms this?
Summary
So, although technically this works, there are numerous reasons why this should not be done. Oracle's documentation states that interruption should only be utilized for cancellations. But if you were to do this, it will clear the interrupt status and the previously waiting thread will receive an InterruptedException.
Alternative
Lets step through a brief, simplified example.
Object obj = new Object;
synchronized (obj) {
while(condition) {
obj.wait();
}
}
A thread here will obtain the monitor.
The thread will begin to wait via wait(), and release the monitor. Always utilize wait() inside a conditional because threads are subject to get spurious wake-ups from wait(). At this point, you have achieved forcing a thread to wait.
Lets investigate how we go about returning the thread to work.
synchronized(obj) {
obj.notify();
}
The notify() will wake up the first waiting thread on the monitor. Now, if you want all waiting threads to wake up, utilize notifyAll() instead. This is the intended purpose and functionality of wait()/notify() and thus should be utilized over wait()/interrupt(). For an additional example, see this article.

Java synchronize block on same object in different methods

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

when the thread will release the lock on object?

I am new for multi-threading.currently i am learning lock and notify and synchronize block . i created a small program to check how wait and notify working with synchronize block , if i will not create any thread(i supposed main thread will get the lock). Below is the code for better understanding .
public class Problem1
{
public void waitForSignal() throws InterruptedException
{
Object obj=new Object();
synchronized (obj) {
obj.wait();
obj.notify();
}
}
public static void main(String args[]) throws InterruptedException
{
Problem1 pb=new Problem1();
pb.waitForSignal();
System.out.println("hello");//controll not come here
}
}
if i run the above program it will stuck. and control neither goes to notify() and nor it will exit the synchronize block. why code behave like this.
i tried to search on google and i found the below statement
wait( ) tells the calling thread to give up the monitor and go to
sleep until some other thread enters the same monitor and calls
notify( ).
what i understand from above statement that , for correct execution of my the program i have to create another thread, that will enter in the same monitor and interrupt the execution of the current lock holding thread. Please make me correct if i am wrong.
Please me to correct above code , so it will work fine without Stuck.
When you call wait, some other thread will have to acquire the lock on obj and call notify or notifyAll to signal the waiting thread to proceed. The easiest way to understand is in the context of the Consumer/Producer problem, and Oracle has a pretty good tutorial about that.
Thread interruption is something entirely different. It is a request for the interrupted thread to check its interrupted status and terminate processing. Brian Goetz has a great article about this in the context of properly handling InterruptedException.

How to understand this simple example of thread?

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.

Categories