I want to wait until thread get's in to wait state. I been trying to use join(see below) but it did not work. How to achieve this?
public Test() {
System.out.print("Started");
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Test.class) {
try {
Test.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("Done");
}
Done is never printed.
Your main thread doesn't progress beyond join()
because the second thread never ends. The second thread never ends because it's waiting for a notification on Test.class
but nobody notifies it.
If you want your main thread to continue executing when the second thread reaches the Test.class.wait();
line, you need to introduce another monitor for this synchronization. The main thread must wait on this monitor and the second thread must notify it when it's ready to switch to the waiting status:
System.out.println("Started");
final Object monitor = new Object();
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finished");
synchronized (monitor) {
monitor.notify(); // Notify the main thread
}
synchronized (Test.class) {
try {
Test.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
synchronized (monitor) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Done");
This code will work, though it looks a bit ugly. It also leaves a hanging thread that will prevent your program from terminating gracefully. You need someone to call Test.class.notify()
if you want this thread to finish.
It's not clear from your question what you're trying to achieve in general. If you want to spawn a thread and wait until it's finished, you don't need those wait()
s and notify()
s, just use join()
:
System.out.println("Started");
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finished");
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Done");
And one more thing: Creating and starting threads in a constructor is a very bad idea. Use a separate method (like initialize()
) for that.