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.
Related
When I try to use methods inside a class in which I extend Thread it does not receive the methods after the run.
My class:
public class PassPhraseValidator<E> extends Thread {
private List<E> list;
private boolean isValid;
private String passPhrase;
public PassPhraseValidator(List<E> list) {
this.list = list;
}
public String getPassPhrase() {
return passPhrase;
}
public boolean isValid() {
return isValid;
}
public void run(){
this.passPhrase = Arrays.toString(list.toArray());
this.isValid = list.stream().filter(e -> Collections.frequency(list, e) > 1).count() == 0;
}
}
So when I execute this class like this:
PassPhraseValidator<Integer> validIntegerPassPhrase = new PassPhraseValidator<>(Arrays.asList(12, 18, 15, 32));
validIntegerPassPhrase.start();
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
It gives me false while it should be true because the run function wasn't ran yet.
What am I doing wrong here? How can I make multithreading part of this? It does work when I directly put it inside the methods.
The last System.out.println statement does not wait for your thread (the run function) to complete.
One way to wait for its completion is to call the join method
validIntegerPassPhrase.join(); //Need to handle the InterruptedException it might throw
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
Explanation
What you are doing is called multithreading. This allows multiple threads to execute code concurrency or in parallel. Programs run on something called the main thread. This means one thread is executing all code systematically; one instruction after another. When introducing another thread like you are, the program execution is being done on different logic at the same time. So, when you execute the start() method on your implementation of the thread class, you are causing it to execute it's respective run() method in the background until; it completes, an exception is thrown, the application is shutdown, or the thread is stopped.
Lets step through your code and analyze the scenario.
Thread object is instantiated by the main thread. Lets call this new thread thread2.
thread2 is started by the main thread.
thread2 and the main thread are both running in parallel. This means code is being executed by both of them (for simplicity) at the same time.
Two possibilities could be occurring for this issue; Java Memory Barrier (beyond the scope of this question but more reference here) or timing. The main thread is most likely reading the print statement before thread2 can finish it's respective run() method.
Solution
An approach may be not to use multi-threading at all. The creation of threads is quite a costly operation and should not be done frequently. Typically, in app's that require multi-threading thread-pools are utilized instead.
Utilize the join() blocking function. Join forces the calling thread (in this case it would be the main thread) to wait for the respective thread to finish execution before continuation.
Implement the thread with use of Promise. This object is a wrapper for the Future class, allowing for the get() method to be blocking. This means the calling thread (in this case it would be the main thread) to wait for the respective thread to finish execution before continuation. An example of Promise's can be found here.
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
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.
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
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.