Where is notifyAll getting called at the end of Thread.join() - java

From jdk 1.7.0_45
The instance method of Thread.join(long miilliseconds) works by making the caller Thread wait on this Thread's Object monitor.Also,the javadoc explicitly states that
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wai t(delay);
now = System.currentTimeMillis() - base;
}
}
}
I don't see notifyAll() getting called so that the Thread calling join() gets the monitor for this Thread's Object
If I am calling t.join(0) on thread t,then I am not implementing notifyAll() in my run() code.So how does the caller thread(the thread which calls t.join() gets notified)

The API documentation says (my emphasis):
Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
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.
The join method is not responsible for the notification, it's the thing doing the waiting.
The notifying would be done by whatever JVM code is responsible for terminating the thread.

You must first understand the notify-wait mechanism. One thread waits (on an object) until another notifies it.
Example code
// in main thread
Thread t1 = new Thread(..);
t1.start();
t1.join();
The implementation of Thread#start() is native. The implementation is required to invoke notifyAll() once the Thread#run() method completes whether abruptly or normally.
This is required so that the thread calling join() can be notified.
In the example above, when the main thread calls join(), it eventually executes
wait(delay);
which is invoked on the Thread instance referenced by t1. This will cause the main thread to block until notify or notifyAll is invoked on the same Thread object which is what the native implementation of start must do, ie. invoke this.notifyAll() (probably implemented in native code).
This is also the reason why developers absolutely should not call wait and notify on Thread instances, so as not to mess with this join implementation.

Related

Can someone explain join method in Java Thread class?

public final synchronized void join(long millis) throwsInterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
How does wait(0) make the main thread wait until it finishes. Thread is calling wait on itself? As far as my understanding it must have a lock on itself to call wait() method? How does it notify the main thread when it finishes?
The documentation explains the logic:
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.
So this implementation relies on the fact that the Thread object does not just represent a thread, but is also an object like any other object in Java. As such, it inherits from Object, has its own monitor and can be synchronized, have threads waiting on it, etc.
It must have a lock on itself to call wait() method?
Yes. And indeed, this method is declared synchronized. So it synchronizes on the Thread instance itself. Once you are inside it, you have the Thread instance's monitor. Then when wait is called, you relinquish it, so other threads can do the same thing.
This might be a bit confusing. Your currently running thread is thread A. You are using join on thread B. The object being synchronized on here is the instance of thread B, and this causes thread A to wait until notifyAll is called on the same (B) instance.
When the thread B finishes, it calls notifyAll on its own instance. So any threads that are blocked in a wait on thread B's instance will be notified.
As far as my understanding it must have lock on itself to call wait() method?
Not on itself, but on the Thread object. And the caller does have a lock on the Thread object. Notice that t.join() is a synchronized method.
How does it notifies to the main thread when it finishes?
Don't get confused by the difference between a Thread and a thread. A Thread instance is a heap object that a program uses to start and manage the life-cycle of a thread of execution in the code. It's methods often are called by other threads than the one it is managing.
If thread A calls t.join(), it will lock the object t, and then it will call t.wait() as many times as it takes until the state of t is Thread.State.TERMINATED.
Remember that, inside each t.wait() call, the lock is released, and then re-acquired before the wait() returns.
In the thread that is managed by t, one of the very last things that it does is, it sets the state of t to TERMINATED, and then calls t.notify(). That will wake up thread A.
obj.wait() causes current thread to sleep, until some another thread call obj.notify() .
t.join() - causes current thread to wait until thread 't' finishes

How do java.lang.Thread static methods work?

E.g. method public static void sleep(long millis). This method causes current thread to sleep, but how does it know, which thread is current? Static methods are object-independent and belong to class, so how does this mechanism work?
This method causes current thread to sleep, but how does it know, which thread is current?
The current thread is managed by the underlying operating system (or the threading system). The underlying (system dependant) thread implementation provides a handle to the current thread:
In case of POSIX threads, there is the API call pthread_self() which returns the thread ID of the currently executing thread. You can think of Thread.currentThread() eventually calling this C function and wrap the thread ID in a Java Thread object which is then returned.
In case of MS Windows, there is the API call GetCurrentThread() which returns the Windows Handle of the currently executing thread. Again, you can think of Thread.currentThread() eventually calling this C function and wrap the Handle in a Java Thread object which is returned.
native methods are special. They have access beyond the Java API.
In this case, to the current thread. You can't use this method to put another thread to sleep - the other thread will have to do this by itself (but you can send it a message, obviously).
This method is always called for the current / executing thread.
It means your current thread will go in sleep mode for a perticlar time.
Ex: if i will write Thread.sleep(1000) thread will go to sleep state for 1000 miliseconds.
We use this menthod mainly to interchange between the thread.In short, it will give chance to another thread for execution.
The current thread is the one actually executing the piece of code. As simple as that.
For instance:
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
System.out.println("Before sleeping!");
Thread.sleep(10000);
System.out.println("After sleeping!");
}
}
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
System.out.println("Main thread!");
}
May output something like:
Before sleeping! // t1
Main thread! // main
Before sleeping! // t2
After sleeping! // t1
After sleeping! // t2

A Mutex for inter-threading usages in Java?

I want a Mutex in Java which let me to wait on it in a thread and release it in another thread. I know that I can use a Semaphore with capacity of 1 but the problem is that the "acquire()" method throws "InterruptedException". Is there any special synchronization way for this purpose in Java?
Luckily, Semaphore provides this method for you :)
public void acquireUninterruptibly()
Acquires a permit from this semaphore, blocking until one is
available. Acquires a permit, if one is available and returns
immediately, reducing the number of available permits by one.
If no permit is available then the current thread becomes disabled for
thread scheduling purposes and lies dormant until some other thread
invokes the release() method for this semaphore and the current thread
is next to be assigned a permit.
If the current thread is interrupted while waiting for a permit then
it will continue to wait, but the time at which the thread is assigned
a permit may change compared to the time it would have received the
permit had no interruption occurred. When the thread does return from
this method its interrupt status will be set.
InterruptedException is not an issue, just wrap it in a loop:
while(true) {
try {
semaphore.acquire();
break;
} catch(InterruptedException e) {
//swallow, continue;
}
}
However this code is not very safe and elegant, but will work providing that you "want to make sure you can acquire a permit!"
if you have a code in which a thread is going to wait then you will definitely have to handle interrupted exception unless you are using synchronized block. Also, What is the problem with interrupted exception?
ThreadA
volatile boolean waitCondition = true
synchronized(lockObject) {
while (waitContidion) {
lockObject.wait();
}
}
ThreadB
synchronized(lockObject) {
waitCondition = false;
lockObject.notifyAll();
}
or use Condition/Signal on Lock instances.
Correct handling of InterruptedException is very important, at least you must set it's interrupted flag with Thread.currentThread().interrupt() method in catch block.

Does Java notify waiting threads implicitly?

I wrote a test app that should never stop. It issues t.wait() (t is a Thread object), but I never call notify. Why does this code end?
Despite the main thread synchronizing on t, the spawned thread runs, so it doesn't lock this object.
public class ThreadWait {
public static void main(String sArgs[]) throws InterruptedException {
System.out.println("hello");
Thread t = new MyThread();
synchronized (t) {
t.start();
Thread.sleep(5000);
t.wait();
java.lang.System.out.println("main done");
}
}
}
class MyThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
java.lang.System.out.println("" + i);
try {
Thread.sleep(500);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
The result is that the main thread waits 5 seconds and during this time worker gives its output. Then after 5 seconds are finished, the program exits. t.wait() does not wait. If the main thread wouldn't sleep for 5 seconds (commenting this line), then t.wait() would actually wait until the worker finishes. Of course, join() is a method to use here, but, unexpectedly, wait() does the same thing as join(). Why?
Maybe the JVM sees that, since only one thread is running, there is no chance to notify the main thread and solves the deadlock. If this is true, is it a documented feature?
I'm testing on Windows XP, Java 6.
You're waiting on a Thread - and while most objects aren't implicitly notified, a Thread object is notified when the thread terminates. It's documented somewhere (I'm looking for it...) that you should not use wait/notify on Thread objects, as that's done internally.
This is a good example of why it's best practice to use a "private" object for synchronization (and wait/notify) - something which only your code knows about. I usually use something like:
private final Object lock = new Object();
(In general, however, it's cleaner to use some of the higher-level abstractions provided by java.util.concurrent if you can. As noted in comments, it's also a good idea to implement Runnable rather than extending Thread yourself.)
The JavaDoc for wait gives the answer: spurious wakeups are possible. This means the JVM is free to end a call to wait whenever it wants.
The documentation even gives you a solution if you don't want this (which is probably always the case): put the call to wait in a loop and check whether the condition you wait for has become true after every wakeup.

Understanding join()

Suppose a thread A is running. I have another thread, B, who's not. B has been started, is on runnable state.
What happens if I call: B.join()?
Will it suspend the execution of A or will it wait for A's run() method to complete?
join() will make the currently executing thread to wait for the the thread it is called on to die.
So - If A is running, and you call B.join(), A will stop executing until B ends/dies.
Join waits till the thread is dead. If you call it on a dead thread, it should return immediately. Here's a demo:
public class Foo extends Thread {
/**
* #param args
*/
public static void main(String[] args) {
System.out.println("Start");
Foo foo = new Foo();
try {
// uncomment the following line to start the foo thread.
// foo.start();
foo.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finish");
}
public void run() {
System.out.println("Foo.run()");
}
}
From http://java.sun.com/docs/books/tutorial/essential/concurrency/join.html
The join method allows one thread to
wait for the completion of another. If
t is a Thread object whose thread is
currently executing,
t.join();
causes the current thread to pause
execution until t's thread terminates.
Overloads of join allow the programmer
to specify a waiting period. However,
as with sleep, join is dependent on
the OS for timing, so you should not
assume that join will wait exactly as
long as you specify.
I can strongly recommend the Java Tutorial as a learning resource.
Calling the join method on a thread causes the calling thread to wait for the thread join() was called on to finish. It does not affect any other threads that are not the caller or callee.
In your example, A would only wait for B to complete if you are calling B.join() from A. If C is calling B.join(), A's execution is unaffected.
I think that if A is the current thread running. A call to B.join() will suspend it until B's run() method completes. Is this correct?
Whichever thread you call B.join() from will block and wait for B to finish.

Categories

Resources