Is there any difference of placing timlesProc(100); inside or outside synchronized block like shown commented line in ThreadA.
According to my understanding there is no difference, because both threads are in running mode and both can be executed in the same time. But according experiments, when timlesProc(100); is inside synchronized - it always runs first, then b.sync.wait(); and no 'wait forever' problem. When timlesProc(100); outside synchronized - I always get 'waiting forever'. Why it is so, or my understanding is not correct?
class ThreadA {
public static void timlesProc(int count)
{
for(int i=0;i<count;i++)
{
System.out.println(Thread.currentThread().getName()+" "+ Integer.toString(i));
}
}
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
//timlesProc(100);
synchronized(b.sync)
{
timlesProc(100);
try
{
System.out.println("Waiting for b to complete...");
b.sync.wait();
System.out.println("waiting done");
} catch (InterruptedException e) {}
}
}
}
class ThreadB extends Thread {
Integer sync = new Integer(1);
public void run() {
synchronized(sync)
{
sync.notify();
System.out.println("notify done");
}
}
}
You have a race condition. If the timlesProc method is outside the synchronized, it's very probable that you will have a context switch and the other Thread will be able to execute acquiring the lock and notifying the main Thread (even if it wasn't waiting). Then when you get to
b.sync.wait();
you wait forever because there is nothing left to notify() it.
If you put the timlesProc inside the synchronized, you reach the wait() and then get notified. The program then finishes.
See Cruncher's answer for another possibility of your program waiting forever.
Actually, even if the timlesProc call is inside the synchronized block, there is still a race condition, just less likely to happen.
If b.start() happens, and it aquires the sync lock before the main thread, then it will still notify first causing the same problem that Sotirios Delimanolis mentions in his answer.
Related
I came across the following e example to implement custom suspend and wait from some website.
// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for (int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
...................
I am more concerned about the ob1.mysuspend() and ob1.myresume() calls. When my suspend is called then ob1 will be placed into the blocking queue associated with the runnable object it is using. When ob1 calls myresume, then how does it work as ob1 is already in waiting queue for the same object, can the waiting object enters another synchronised method and then signals notify to itself?How does this work?What am I missing?
The thread is written so that while an instance of NewThread is running, another thread can call mysuspend to suspend that running thread. Again, a thread other than the suspended thread calls myresume to resume the suspended thread.
There also appears to be a data race because mysuspend writes to suspendFlag without any synchronization. That means, the thread that needs to be suspended may not see that write immediately. mysuspend must be declared synchronized, or suspendFlag must be volatile.
This code is flat out broken.
Straight up broken: JMM violation
The mysuspend method (which should be named mySuspend, by the way) updates a field that is then read from another thread, and isn't synchronized. This is an error - and a really nasty one because you cannot reliably test that it is an error. The Java Memory Model (JMM) states that any write to a field may be observable or not, at the discretion of the JVM implementation, unless a so-called Happens-Before/Happens-After relationship is established (there are many ways to do it; usually you do so via synchronized, volatile, or some other concurrency tool built on these primitives, such as the latches and queues in the java.util.concurrent package).
You do not establish such a relationship here, meaning, that suspendFlag = true results in a schroedingers cat variable: The other thread that reads this field may read true or false, the JVM gets to decide what you see. Hence: A bug, and, untestable. bad. Any field that is read/written to by multiple threads needs to be written extremely carefully.
Mark that method synchronized, that's a good first step.
Wait and Notify
You've got it flipped around: You must in fact hold the synchronized lock on x when you invoke wait on x (here, x is this).
To call x.wait() (you are calling this.wait(), effectively), you must first be in a synchronized(x) block. Once the wait 'goes through', the code releases the lock (other synchronized(x) blocks can run). To invoke x.notify() you must also hold that lock.
wait does not return until the lock is re-established.
In other words:
public void foo() {
wait();
}
will fail at runtime. Try it. Guaranteed exception. In the mean time, this:
public void foo() {
synchronized (this) {
// code before wait
wait();
// code after wait
}
}
is executed as if it is written like this:
public void foo() {
synchronized (this) {
// code before wait
release_lock(this);
this.wait();
acquire_lock(this);
// code after wait
}
}
Where acquire_lock is guaranteed to actually take a while (because by definition whatever invoked notify() to wake you up is currently holding it! So wait is always a two-hit thing: You need to be both notified AND the lock needs to be reacquired before your code will continue). Except, of course, acquire_lock and release_lock don't exist, and unlike this hypothetical code, wait() is more atomic than that.
I am using multi-threading in java for my program.
I have run thread successfully but when I am using Thread.wait(), it is throwing java.lang.IllegalMonitorStateException.
How can I make a thread wait until it will be notified?
You need to be in a synchronized block in order for Object.wait() to work.
Also, I recommend looking at the concurrency packages instead of the old school threading packages. They are safer and way easier to work with.
EDIT
I assumed you meant Object.wait() as your exception is what happens when you try to gain access without holding the objects lock.
wait is defined in Object, and not it Thread. The monitor on Thread is a little unpredictable.
Although all Java objects have monitors, it is generally better to have a dedicated lock:
private final Object lock = new Object();
You can get slightly easier to read diagnostics, at a small memory cost (about 2K per process) by using a named class:
private static final class Lock { }
private final Object lock = new Lock();
In order to wait or notify/notifyAll an object, you need to be holding the lock with the synchronized statement. Also, you will need a while loop to check for the wakeup condition (find a good text on threading to explain why).
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
To notify:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
It is well worth getting to understand both Java language and java.util.concurrent.locks locks (and java.util.concurrent.atomic) when getting into multithreading. But use java.util.concurrent data structures whenever you can.
I know this thread is almost 2 years old but still need to close this since I also came to this Q/A session with same issue...
Please read this definition of illegalMonitorException again and again...
IllegalMonitorException is thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
This line again and again says, IllegalMonitorException comes when one of the 2 situation occurs....
1> wait on an object's monitor without owning the specified monitor.
2> notify other threads waiting on an object's monitor without owning the specified monitor.
Some might have got their answers... who all doesn't, then please check 2 statements....
synchronized (object)
object.wait()
If both object are same... then no illegalMonitorException can come.
Now again read the IllegalMonitorException definition and you wont forget it again...
Based on your comments it sounds like you are doing something like this:
Thread thread = new Thread(new Runnable(){
public void run() { // do stuff }});
thread.start();
...
thread.wait();
There are three problems.
As others have said, obj.wait() can only be called if the current thread holds the primitive lock / mutex for obj. If the current thread does not hold the lock, you get the exception you are seeing.
The thread.wait() call does not do what you seem to be expecting it to do. Specifically, thread.wait() does not cause the nominated thread to wait. Rather it causes the current thread to wait until some other thread calls thread.notify() or thread.notifyAll().
There is actually no safe way to force a Thread instance to pause if it doesn't want to. (The nearest that Java has to this is the deprecated Thread.suspend() method, but that method is inherently unsafe, as is explained in the Javadoc.)
If you want the newly started Thread to pause, the best way to do it is to create a CountdownLatch instance and have the thread call await() on the latch to pause itself. The main thread would then call countDown() on the latch to let the paused thread continue.
Orthogonal to the previous points, using a Thread object as a lock / mutex may cause problems. For example, the javadoc for Thread::join says:
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.
Since you haven't posted code, we're kind of working in the dark. What are the details of the exception?
Are you calling Thread.wait() from within the thread, or outside it?
I ask this because according to the javadoc for IllegalMonitorStateException, it is:
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
To clarify this answer, this call to wait on a thread also throws IllegalMonitorStateException, despite being called from within a synchronized block:
private static final class Lock { }
private final Object lock = new Lock();
#Test
public void testRun() {
ThreadWorker worker = new ThreadWorker();
System.out.println ("Starting worker");
worker.start();
System.out.println ("Worker started - telling it to wait");
try {
synchronized (lock) {
worker.wait();
}
} catch (InterruptedException e1) {
String msg = "InterruptedException: [" + e1.getLocalizedMessage() + "]";
System.out.println (msg);
e1.printStackTrace();
System.out.flush();
}
System.out.println ("Worker done waiting, we're now waiting for it by joining");
try {
worker.join();
} catch (InterruptedException ex) { }
}
In order to deal with the IllegalMonitorStateException, you must verify that all invocations of the wait, notify and notifyAll methods are taking place only when the calling thread owns the appropriate monitor. The most simple solution is to enclose these calls inside synchronized blocks. The synchronization object that shall be invoked in the synchronized statement is the one whose monitor must be acquired.
Here is the simple example for to understand the concept of monitor
public class SimpleMonitorState {
public static void main(String args[]) throws InterruptedException {
SimpleMonitorState t = new SimpleMonitorState();
SimpleRunnable m = new SimpleRunnable(t);
Thread t1 = new Thread(m);
t1.start();
t.call();
}
public void call() throws InterruptedException {
synchronized (this) {
wait();
System.out.println("Single by Threads ");
}
}
}
class SimpleRunnable implements Runnable {
SimpleMonitorState t;
SimpleRunnable(SimpleMonitorState t) {
this.t = t;
}
#Override
public void run() {
try {
// Sleep
Thread.sleep(10000);
synchronized (this.t) {
this.t.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Thread.wait() call make sense inside a code that synchronizes on Thread.class object. I don't think it's what you meant.
You ask
How can I make a thread wait until it will be notified?
You can make only your current thread wait. Any other thread can be only gently asked to wait, if it agree.
If you want to wait for some condition, you need a lock object - Thread.class object is a very bad choice - it is a singleton AFAIK so synchronizing on it (except for Thread static methods) is dangerous.
Details for synchronization and waiting are already explained by Tom Hawtin.
java.lang.IllegalMonitorStateException means you are trying to wait on object on which you are not synchronized - it's illegal to do so.
Not sure if this will help somebody else out or not but this was the key part to fix my problem in user "Tom Hawtin - tacklin"'s answer above:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
Just the fact that the "lock" is passed as an argument in synchronized() and it is also used in "lock".notifyAll();
Once I made it in those 2 places I got it working
I received a IllegalMonitorStateException while trying to wake up a thread in / from a different class / thread. In java 8 you can use the lock features of the new Concurrency API instead of synchronized functions.
I was already storing objects for asynchronous websocket transactions in a WeakHashMap. The solution in my case was to also store a lock object in a ConcurrentHashMap for synchronous replies. Note the condition.await (not .wait).
To handle the multi threading I used a Executors.newCachedThreadPool() to create a thread pool.
Those who are using Java 7.0 or below version can refer the code which I used here and it works.
public class WaitTest {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitHere(long waitTime) {
System.out.println("wait started...");
lock.lock();
try {
condition.await(waitTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println("wait ends here...");
}
public static void main(String[] args) {
//Your Code
new WaitTest().waitHere(10);
//Your Code
}
}
For calling wait()/notify() on object, it needs to be inside synchronized block. So first you have to take lock on object then would be possible to call these function.
synchronized(obj)
{
obj.wait()
}
For detailed explanation:
https://dzone.com/articles/multithreading-java-and-interviewspart-2
wait(), notify() and notifyAll() methods should only be called in syncronized contexts.
For example, in a syncronized block:
syncronized (obj) {
obj.wait();
}
Or, in a syncronized method:
syncronized static void myMethod() {
wait();
}
I made this sample to understand how Wait-Notify works:
public class WaitingTest implements Runnable {
Thread b = new Thread();
int total;
public static void main(String[] args){
WaitingTest w = new WaitingTest();
}
public WaitingTest(){
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + total);
}
}
#Override
public void run(){
synchronized(b){
for(int i=0; i<100 ; i++){
total += i;
System.out.println(total);
}
b.notify();
}
}
}
But I'm stuck here for hours and I can't understand why it's not quite working. My output should be more than 0, but its always zero...I was wondering if its becuase of the usage of different threads, but Im not really sure..What am I missing?
I think you have some serious holes in your understanding. You've declared a Thread
Thread b = new Thread();
and started it in the constructor
b.start();
That Thread will start and die right away since it has no Runnable attached to it.
It just so happens that when a Thread dies, it calls notify() on itself and since you are synchronized on that same Thread object, your wait()ing thread will be awoken. You also have a race here. If the Thread ends before the main thread reaches the wait(), you will be deadlocked.
Also, there is no reason for run() to be called, which is why total remains 0.
Any object can be synchronized on, it doesn't have to be a Thread. And since Thread has that weird behavior of notify()ing itself, you probably shouldn't use it.
You should go through both the Thread tutorials and the synchronization tutorials.
Apart from the problem with how you have arranged your threads, you have a incorrect use of wait()/notify()
notify() is stateless. If no thread is waiting, nothing will be notified. If you wait() later it will not be notified.
wait() can wake spuriously. Just because wait() woke doesn't mean anything notified it.
This means you need to associate wait/notify with state (in fact it's rather pointless without it)
For example.
// to notify
synchronized(lock) {
signalled = true;
lock.notify();
}
// to wait
synchronized(lock) {
while(!signalled)
lock.wait();
}
Why usually threading samples put so many code in synchronized block. According to my understanding in following case synchronized is used just for locking b for wait and notify:
Main class ThreadA :
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
System.out.println(Thread.currentThread().getName());
}
}
}
and class ThreadB:
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this)
{
System.out.println();
for(int i=0;i<100;i++)
{
System.out.println(Thread.currentThread().getName());
total += i;
}
notify();
}
}
}
What will change if I put just wait and notify in synchronized block:
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println("Waiting for b to complete...");
synchronized(b) { b.wait();}
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
System.out.println(Thread.currentThread().getName());
}
}
According to my understanding in following case synchronized is used just for locking b for wait and notify
Your understanding is wrong.
synchronized is also used for:
Mutual exclusion, to ensure that only one thread executes code "guarded" by a particular monitor at a time
Ensuring memory access across threads is correct (that one thread sees changes made by another thread)
What will change if I put just wait and notify in synchronized block:
In this particular case, it will make a difference based on a race condition - in the original code, if the new thread starts executing before the synchronized block is reached in the original thread, it won't get as far as "Waiting for b to complete" until the second thread has finished... at which point it will block forever in wait.
Note that it's a really bad idea to wait on Thread monitors, as wait/notify is used internally by Thread.
In short, the example you've used is a bad one to start with in various ways - but synchronization is used for more than just wait/notify.
Please note that total += i is not an atomic operation in Java. So you have to sync also this construct.
You also have not to sync notify() and wait() because their locks are handled internally.
Expanding on the answer by #sk2212, the increment operation is not atomic, but there is an equivalent atomic operation provided in high-level concurrency primitives.
I know that there are a few threads open regarding this topic, but I'm just looking for a VERY ELEMENTARY example of how to use wait() and notify() in Java. By "VERY ELEMENTARY," I mean simply printing something out. Thanks.
EDIT: Here's what I have tried thus far and I get an IllegalMonitorStateException:
public void waiting() {
for(int i = 0; i < 10; i++) {
if(i == 5)
try {
this.wait();
} catch (InterruptedException e) {
}
else
System.out.println(i);
}
System.out.println("notify me now");
this.notify();
}
wait and notify are used in synchronized block while using threads to suspend and resume where left off.
Wait immediately looses the lock, whereas Nofity will leave the lock only when the ending bracket is encountered.
public class Mythread implements Runnable{
public synchronized void goo(){
System.out.println("Before Wait");
wait();
System.out.println("After Wait");
}
public synchronized void foo(){
System.out.println("Before Notify");
notify();
System.out.println("After Notify");
}
public class Test{
public static void main(String[] args){
Thread t = new Thread(new Mythread);
t.start();
}
}
Your IllegalMonitorStateException is due to the fact that you must synchronize on the object before calling wait or notify. So
this.wait
needs to be
synchronized(this) {
this.wait();
}
Your example won't run because you'll never get to the notify call... as soon as your thread hits wait, it will suspend and advance no further. For wait / notify to work, you have to have two threads. One thread suspends when the wait method is invoked, and eventually, the second thread calls synchronized(this) { this.notify() } to cause the first thread to wake up and continue executing below the wait call.
The synchronization is required because you would ordinarily check some condition before waiting, ie,
synchronized(this) {
if(! this.isReady) {
this.wait();
}
}
You need to synchronize to make sure no other thread changes the state of the isReady flag between the line where you check the variable and the line where you wait. So your notify code would
synchronized(this) {
isReady = true;
this.notify();
}
Now the order of the method calls doesn't matter. If you notify first, no thread will wake up, but that's ok, because you aren't going to sleep since isReady = true. If you go to sleep first, isReady = true does nothing, but the notify call wakes up the thread. Finally, the synchronization ensures that you don't check the variable in thread A, then have thread B set the variable and notify (doing nothing), then have thread A go to sleep and never wake up.
Hope that helps.
wait() and notify() are used to synchronise threads: a thread can be told to wait(), and will not continue doing anything until it receives the notify() call.
The basic idea with these functions is that wait() suspends a thread (puts it to sleep), and notify() causes a thread to pick up where it left when it went to sleep.
Take a look at: this or just look up simple prodcuer consumer problem java on google. I am sure you will find something to suit your needs.
See this example on guarded blocks from the oracle java site - it includes a worked example of a simple producer-consumer problem.