Wait() / notify() synchronization - java

I'm trying to check how wait/notify works in java.
Code:
public class Tester {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
synchronized (t) {
try {
System.out.println("wating for t to complete");
t.wait();
System.out.println("wait over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (this) {
System.out.println("entering syncronised block");
notify();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("leaving syncronized block");
}
System.out.println("leaving run method");
}
}
Output Returned
wating for t to complete
entering run method
entering syncronised block
//sleep called
leaving syncronized block
leaving run method
wait over
I was expecting when notify() is executed the wait will be over & System.out.println("wait over"); will get printed. But it seems it only gets printed when t finished its run().

Object monitor locks need to be performed a single reference of the same lock...
In your example you are waiting on an instance of the Thread, but using notify from the Runnable. Instead, you should use a single, common lock object...for example
public class Tester {
public static final Object LOCK = new Object();
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
synchronized (LOCK) {
try {
System.out.println("wating for t to complete");
LOCK.wait();
System.out.println("wait over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (LOCK) {
System.out.println("entering syncronised block");
LOCK.notify();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("leaving syncronized block");
}
System.out.println("leaving run method");
}
}
}
Output...
wating for t to complete
entering run method
entering syncronised block
leaving syncronized block
wait over
leaving run method
wait over and leaving run method could change positions depending on the thread scheduling.
You could try putting the sleep out side the synchronized block. This will release the monitor lock allowing the wait section to continue running (as it can't start until the lock is released)
public static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (LOCK) {
System.out.println("entering syncronised block");
LOCK.notify();
System.out.println("leaving syncronized block");
}
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("leaving run method");
}
}

Answer to updated code :
From Thread.sleep() javadoc:
Causes the currently executing thread to sleep (temporarily cease execution) for the
specified number of milliseconds, subject to the precision and accuracy of system timers
and schedulers. The thread does not lose ownership of any monitors.
If you call Thread.sleep while inside a synchronized block, other threads won't be able to enter the synchronized block. You should never do time consuming tasks while in a synchronized block to avoid this.

Note (as others pointed out as well) that you have to use the same object for locking/synchronizing in both threads.
If you want your main thread to continue immediately after notify is called, you have to relinquish the lock temporarily. Otherwise wait will get called only after the secondary thread leaves the synchronized block. And it's never a good idea to keep a lock in a long running computation!
One way how to achieve is to use wait(int) on the lock instead of sleep, because wait releases the synchronization lock temporarily:
public class Tester {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
synchronized (lock) {
try {
System.out.println("wating for t to complete");
lock.wait();
System.out.println("wait over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
synchronized (lock) {
System.out.println("entering syncronised block");
lock.notify();
try {
lock.wait(1000); // relinquish the lock temporarily
} catch (InterruptedException ex) {
System.out.println("got interrupted");
}
System.out.println("leaving syncronized block");
}
System.out.println("leaving run method");
}
}
}
However, using these low-level primitives can be very error prone and I'd discourage from using them. Instead, I'd suggest you to use Java's high-level primitives for that. For example, you can use CountDownLatch which lets one thread wait until other threads count down to zero:
import java.util.concurrent.*;
public class TesterC {
private static final CountDownLatch latch = new CountDownLatch(1);
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
System.out.println("wating for t to complete");
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait over");
}
static class MyRunnable implements Runnable {
public void run() {
System.out.println("entering run method");
try {
latch.countDown();
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("got interrupted");
}
System.out.println("leaving run method");
}
}
}
Here you don't have to synchronize anything, the latch does everything for you. There are many other primitives you can use - semaphores, an exchanger, thread-safe queues, etc. Explorer the java.util.concurrent package.
Perhaps even better solution is to use even higher level API, such as Akka provides. There you work with Actors or Software transactional memory, which can be composed easily and spare you of most of concurrency issues.

Related

What can cause IllegalMonitorStateException in the given sample code

I am trying to learn java concurrency programming. Kindly check my sample code and help me understanding why I'm getting "java.lang.IllegalMonitorStateException" even though I have called wait() and notify in a synchronized context.
public class Test {
public static void main(String[] args) throws Exception {
Test t1 = new Test();
t1.m1();
}
private void m1() {
Example ex = new Example();
Thread t1 = new Thread(ex);
t1.start();
synchronized (ex) {
System.out.println("waiting");
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Example implements Runnable {
#Override
public void run() {
System.out.println("Running");
notifyMethod();
}
private void notifyMethod() {
System.out.println("Notifying");
synchronized (this) {
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
notify();
}
}
}
}
I expect out of "waiting,running,notifying" but the actual output is:
waiting
Running
java.lang.IllegalMonitorStateException
Notifying
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at examples.Test.m1(Test.java:18)
at examples.Test.main(Test.java:8)
First of, I think synchonizing on a Runnable isn't a good idea (Example in your case). You either synchonize on this or, even better, on a dedicated Object, that is lock in my example. Edit: Synchronizing on a Runnable is the same as using this but for me it looks better. Guts tell me there might be something more to that, but I'm not an expert in this field. Dedicated lock Object is always better, read this article if you want to find out more on the topic.
Then, while synchonizing on a lock, you have to call wait() on that same object: lock.wait(). If you synchronize on this, then you call this.wait() or just wait().
When you want to notify the waiting thread, you again have to synchronize on the lock and call notify() on that object: lock.notify(). Both the monitor in the synchronize and the object on which you call notify() have to be the exact same object you have called wait() on.
Here is a code that works:
public class Test {
public static final Object lock = new Object();
public static void main(String[] args) throws Exception {
Test t1 = new Test();
t1.m1();
}
private void m1() {
Example ex = new Example();
Thread t1 = new Thread(ex);
t1.start();
synchronized (lock) {
System.out.println("waiting");
try {
lock.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static class Example implements Runnable {
#Override
public void run() {
System.out.println("Running");
notifyMethod();
}
private void notifyMethod() {
System.out.println("Notifying");
synchronized (lock) {
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
lock.notify();
}
}
}
}

How can I start a thread from another and restart a thread after execution?

I have 2 threads, the "main" thread which starts a secondary thread to run a little process.
The "main" thread must wait for the secondary thread for a few of seconds to complete the process, after that time, the "main" thread must start again no matter what happened with the process of the secondary thread.
If the secondary process ended earlier, the "main" thread must start to work again.
How can I start a thread from another, wait for the end of execution, and restart the thread after?
I have a code here, but the ExampleRun class, must wait, for example, 10 sec and start again, no matter what happend with MyProcess
public class ExampleRun {
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
System.out.println("Error");
}
}
}
}
public class MyProcess extends Thread {
public void run() {
System.out.println("start");
synchronized (this) {
for (int i = 0; i < 5; i++) {
try {
System.out.println("I sleep");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
System.out.println("Wake up");
notify();
}
}
}
The simplest way to achieve what you want is to use Thread.join(timeout).
Also, do not use synchronized, wait, or notify on Thread objects. This will interfere with the Thread.join implementation. See the documentation for details.
Here's what your main program would look like:
public static void main(String[] args) {
MyProcess t = new MyProcess();
t.start();
try {
t.join(10000L);
} catch (InterruptedException ie) {
System.out.println("interrupted");
}
System.out.println("Main thread resumes");
}
Note that when the main thread resumes after the join() call, it can't tell whether the child thread completed or whether the call timed out. To test this, call t.isAlive().
Your child thread of course could do anything, but it's important for it not to use synchronized, wait, or notify on itself. For example, here's a rewrite that avoids using these calls:
class MyProcess extends Thread {
public void run() {
System.out.println("MyProcess starts");
for (int i = 0; i < 5; i++) {
try {
System.out.println("MyProcess sleeps");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyProcess finishes");
}
}
You can do this with a simple lock method:
public static void main (String[] args)
{
// create new lock object
Object lock = new Object();
// create and start thread
Thread t = new Thread(() ->
{
// try to sleep 1 sec
try { Thread.sleep(1000); }
catch (InterruptedException e) { /* do something */ }
// notify main thread
synchronized (lock) { lock.notifyAll(); }
};
t.start();
// wait for second thread to finish
synchronized (lock)
{
while (t.isAlive())
lock.wait();
}
// second thread finished
System.out.println("second thread finished :)");
}
You could call Thread.join() on the Thread you want to wait for, per the Javadoc,
Waits for this thread to die.
Alternatively, you could use a Future and simply call get(), from its' Javadoc,
Waits if necessary for the computation to complete, and then retrieves its result.

Notify not getting the thread out of wait state

I am trying to use 2 threads. 1 thread prints only odd number and the other thread prints only even number and It has to be an alternative operation.
Eg:
Thread1 1
Thread2 2
Thread1 3
Thread2 4
and so on..
Below is the program, please let me know where I am going wrong as the thread1 is not coming out of wait state even when the thread2 is notifying it..
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (t) {
try {
t.notify();
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
Problem is that in one case you are taking lock on Thread t [synchronized (t) ] while in other case you are taking lock on TheadA object itself [synchronized(this)].
If you want threads to talk to each other then both should take lock on same object only then wait notify will work as you expect.
Edit:
There is another problem in your program, you are not using any variable to coordinate between 2 threads. SO you may see output like this 2,1,4,3...so on. Point is threads will work alternately but not in sequence.
So you should share a single variable between 2 threads which should be incremented.
Second issue is you are not taking care of spurious wake up calls [read some docs on this], you should always have wait called inside a while loop.
Modified my code based on the answer provided by Lokesh
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (ta) {
try {
ta.notify();
ta.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
You have a real confusion of threads and locks. I suggest you create one and only one object to use for locking to start with as you don't appear to have a clear idea what you are locking.
If you notify() and nothing is listening, the signal is lost. However, a wait() can wake spuriously.
For this reason, a notify() should be accompanied by a state change and a wait() should be in a loop checking that change.

Simultaneous access to a Java synchronized block using threads?

How can two threads access a synchronized block simultaneously? That is, how can I make one thread give the chance for the other thread to execute a synchronized block, even before this thread finishes the execution of the same synchronized block?
See wait(), notify(), and notifyAll().
Edit: The edit to your question is incorrect. The sleep() method does not release the monitor.
For example:
private static final Object lock = new Object();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(new One());
executorService.execute(new Two());
}
static class One implements Runnable {
#Override
public void run() {
synchronized (lock) {
System.out.println("(One) I own the lock");
System.out.println("(One) Giving up the lock and waiting");
try {
lock.wait();
} catch (InterruptedException e) {
System.err.println("(One) I shouldn't have been interrupted");
}
System.out.println("(One) I have the lock back now");
}
}
}
static class Two implements Runnable {
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.err.println("(Two) I shouldn't have been interrupted");
}
synchronized (lock) {
System.out.println("(Two) Now I own the lock (Two)");
System.out.println("(Two) Giving up the lock using notify()");
lock.notify();
}
}
}
It sounds like you might want to consider using more than one synchronized block, particularly if there's a blocking operation that one thread is getting caught on and thus blocking another thread that wants to execute something else in the block.
A synchronized block is a block of code which can (by definition) only be accessed by one thread at a time.
Saying that you want another thread to enter this block while another thread also currently processes it, does make the synchronized block scheme useless.
You probably want to split the synchronized block into many other ones.
The only way I can see if one thread calls wait() on monitor object. Then it will release monitor and wait for notification while other thread can execute synchronized block. Then other thread will have to call notify()/notifyAll() so first thread gets monitor back and continue.
A thread can release its monitor using lock.wait(). Another thread can then pick up the monitor and enter the synchronized block.
Example:
public class MultipleThreadsInSynchronizedBlock {
public static void main(String... args) {
final Object lock = new Object();
Runnable runnable = new Runnable() {
public void run() {
synchronized (lock) {
System.out.println("Before wait");
try {
lock.wait();
} catch (InterruptedException e) {
}
System.out.println("After wait");
}
}
};
new Thread(runnable).start();
new Thread(runnable).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
synchronized (lock) {
lock.notifyAll();
}
}
}
This prints:
Before wait
Before wait
After wait
After wait
However it's not a "hack" to allow a mutually exclusive block to be run non-atomically. If you're going to use very low-level synchronization primitives like this you need to know what you're doing.

Understanding Java Wait and Notify methods

I have a following program:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleWaitNotify implements Runnable {
final static Object obj = new Object();
static boolean value = true;
public synchronized void flag() {
System.out.println("Before Wait");
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
System.out.println("After Being Notified");
}
public synchronized void unflag() {
System.out.println("Before Notify All");
obj.notifyAll();
System.out.println("After Notify All Method Call");
}
public void run() {
if (value) {
flag();
} else {
unflag();
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(4);
SimpleWaitNotify sWait = new SimpleWaitNotify();
pool.execute(sWait);
SimpleWaitNotify.value = false;
SimpleWaitNotify sNotify = new SimpleWaitNotify();
pool.execute(sNotify);
pool.shutdown();
}
}
When I wait on obj, I get the following exception Exception in thread "pool-1-thread-1" java.lang.IllegalMonitorStateException: current thread not owner for each of the two threads.
But if I use SimpleWaitNotify's monitor then the program execution is suspended. In other words, I think it suspends current execution thread and in turn the executor. Any help towards understanding what's going on would be duly appreciated.
This is an area1 where the theory and javadoc seem straightforward, and since there aren't many examples, conceptually left a big gap in me.
You're calling wait and notifyAll on obj, but you're synchronizing on this (because you've got synchronized methods).
In order to wait or notify, you need to "own" the monitor first. Unsynchronize the methods, and synchronize on obj instead:
public void flag() {
System.out.println("Before Wait");
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
}
System.out.println("After Being Notified");
}
public void unflag() {
System.out.println("Before Notify All");
synchronized (obj) {
obj.notifyAll();
}
System.out.println("After Notify All Method Call");
}
Either synchronize on obj, or call wait and notify on this. The calling thread must hold the monitor of the same object on which these methods are called.
For example,
synchronized void flag() {
System.out.println("Before Wait");
try {
wait();
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
System.out.println("After Being Notified");
}
In this example, the lock is held on this (when the modifier synchronized is used on a instance method, the monitor of the instance is acquired). So, the wait() method may be invoked on the implied instance this.
In order to coordinate the two threads, they need to share the same lock. The original version had a static obj that could be used as a lock, but it wasn't used in the synchronized blocks. Here is a better example:
class SimpleWaitNotify implements Runnable {
private final Object lock;
private final boolean wait;
SimpleWaitNotify(Object lock, boolean wait) {
this.lock = lock;
this.wait = wait;
}
public void flag() {
synchronized (lock) {
System.out.println("Before Wait");
try {
lock.wait();
System.out.println("After Being Notified");
} catch (InterruptedException ex) {
System.out.println("Thread interrupted");
}
}
}
public void unflag() {
synchronized(lock) {
System.out.println("Before Notify All");
lock.notifyAll();
System.out.println("After Notify All Method Call");
}
}
public void run() {
if (wait) {
flag();
} else {
unflag();
}
}
public static void main(String[] argv) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(4);
Object shared = new Object();
SimpleWaitNotify sWait = new SimpleWaitNotify(shared, true);
pool.execute(sWait);
SimpleWaitNotify sNotify = new SimpleWaitNotify(shared, false);
pool.execute(sNotify);
pool.shutdown();
}
}
Rather putting the direct statement pool.shutdown(), try as below.
while (!service.isTerminated())
{
service.shutdown();
}
So it will wait for till all the threads execution completes.

Categories