I have a method which uses CyclicBarrier as shown below:
public void getMessage(Message obj){
CyclicBarrier barrier = new CyclicBarrier(1, new Runnable() {
#Override
public void run() {
synchronized(obj){
System.out.println("--The End --");
}
}
});
executor.execute(new Runnable() {
#Override
public void run() {
synchronized(obj){
//Perform some routine with message object
}
try {
barrier.wait();//java.lang.IllegalMonitorStateException thrown on this line
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
At the point where i wait for the routine to finish executing, i get:
Exception in thread "pool-2-thread-3"
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
Do anyone knows what I am doing wrong here?
In order to call wait() on any object, the current thread has to own its monitor. You're calling barrier.wait() without any synchronized(barrier).
However, you may have meant to use the await() method (on CyclicBarrier) instead of wait(). It's hard to say, as it's not clear what you're trying to achieve.
yeah, you need to gain the monittor of barrier like so:
synchhronized(barrier){
try {
barrier.wait();//java.lang.IllegalMonitorStateException not thrown on this line
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Maybe you did want to use await() instead that wait()?
wait is used to block a thread over a specific object and it is a feature of every object, but in your case you are calling it without taking the monitor of it. You should call wait from inside the same obect or use a synchronized block over barrier itself.
You need to acquire lock before using the barrier object.
Regards,
Dheeraj Joshi
The cyclicBarrier is not intended to be used as you do here : participating threads are expected to call the blocking "await()" method.
As a side note, a CyclicBarrier with a count of 1 is totally useless : its intent is to allow a certain number of threads (the barrier count) to wait for each other before continuing.
Maybe you should consider changing your whole algorithm, especially if you're not sure about how concurrency stuff works.
Related
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 have this piece of code:
Profile a = randomProfile();
Thread workerA = new Thread(new Downloader(a));
workerA.start();
Profile b = randomProfile();
Thread workerB = new Thread(new Downloader(b));
workerB.start();
synchronized (workerA) {
try {
workerA.wait();
} catch (InterruptedException e) {
System.out.println("Error on background thread!");
System.exit(1);
}
}
synchronized (workerB) {
try {
workerB.wait();
} catch (InterruptedException e) {
System.out.println("Error on background thread!");
System.exit(1);
}
}
And a Downloader class which implements the Runnable interface, and its run() method looks like:
#Override
public void run() {
synchronized (this) {
//work...
notify();
}
}
Now this is working as intented, sometimes. Most of the time though, it seems to get stuck in the second synchronized block (it always gets through the first one).
Am I doing something wrong?
Also do I have some conceptual error, e.g. this implementation doesn't give me any advantage over a single thread?
The wait() is invoked on the Thread objects but the notify() is invoked on the Downloader objects.
The background threads should therefore run without a problem (although completely unsynchronized), and the main thread should always block to infinity in the first synchronized block because there's no-one to wake it up.
Where this case is special is that you invoked wait() on the Thread objects themselves, which is discouraged (and by this I really mean: forbidden). When a thread terminates, it invokes notifyAll() on itself, so when workerA finishes, you get out of the first synchronized block. But by the time the second synchronized block is reached, workerB is already finished, so the second wait() will never end.
Whether there is a conceptual error depends on what you were trying to achieve. From the code it looks very much like what you tried to do is join() the background threads.
Consider there are two threads which are waiting to execute synchronized block. Now one get chance one is waiting in this case do I really need to call notify() ? I think as synchronized block execution completes other thread will release the lock ? what is the exact use of notify() method ?
Threading experts please explain ?
No, you wouldn't need to use notify() in that case. You are correct, the thread that had to wait to acquire the lock would automatically proceed after the lock was released.
The notify() method works in conjunction with the wait() method. When one thread invokes wait(), it may release the lock and begin waiting. One of the conditions that can end the wait is when another thread invokes notify(). Both wait() and notify() must be invoked on an instance on which the current thread is synchronized.
This can be used, for example, to create a channel between two threads, where one thread is consuming information produced by another. If the consumer runs out of information to process, it might wait() until the producer does a notify() that more data are available.
When a thread enter synchronized block and calls wait the lock acquired while entering the synchronized block is released and the thread waits for other thread to notify it in which case it will reacquire the lock and proceed.Lock is again released when the thread comes out of the synchronized block.
from the doc,
Wakes up a single thread that is waiting on this object's monitor. If
any threads are waiting on this object, one of them is chosen to be
awakened. The choice is arbitrary and occurs at the discretion of the
implementation. A thread waits on an object's monitor by calling one
of the wait methods.
so if an object is waiting by calling a wait method. then you can awake them using notify.
Description
The java.lang.Object.notify() wakes up a single thread that is waiting
on this object's monitor. If any threads are waiting on this object,
one of them is chosen to be awakened. The choice is arbitrary and
occurs at the discretion of the implementation. A thread waits on an
object's monitor by calling one of the wait methods.
For more information refer below links.
notify()
Documentation
Doc
I hope it will help you.
Like if you are using Multiple threads the method is synchronized which means it will share among all the threads but any thread will use it after the execution another thread.
and if there is any change is made by any thread then it will visible for all by using notify method below code is example for that:
class Detail {
public String name = "", sername = "";
Scanner sc;
public synchronized String getData() {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return name+""+sername;
}
public synchronized void show() {
try {
name = "hello";
sername = "hii";
Thread.sleep(1000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
notify();
}
}
class Data1 extends Thread {
Detail detail;
public Data1(Detail detail1)
{
// super("1");
this.detail = detail1;
start();
}
public void run()
{
System.out.println("name is :"+detail.getData());
}
}
class Data2 extends Thread {
Detail detail2;
public Data2(Detail detail1)
{
//super("2");
this.detail2 = detail1;
start();
}
public void run()
{
detail2.show();
}
}
public class SyncDemo {
public static void main(String ar[])
{
Detail det = new Detail();
Data1 d1= new Data1(det);
Data2 d2= new Data2(det);
}
}
I'm developing an Android app.
I have two threads. The first one has to wait the second one.
I have this code on the first thread run method:
#Override
public void run() {
synchronized (this.secondThread) {
this.secondThread.wait();
}
[...]
}
And on my second thread:
#Override
public void run() {
synchronized (MyClass.myLock) {
try {
// Do something important here
}
catch (Exception ex)
{
// manage exception
return;
}
finally {
// do something...
}
}
synchronized (this) {
this.notify();
}
[...]
}
As you can see, there is a return inside catch block.
With this code, will first thread get notified if an exception occurs on the second thread?
will first thread get notified if an exception occurs on the second
thread?
Answer is no. Unless you explicitly notify() in catch block before returning, the other thread will not wake up
Answer is no. In order to get both notify the has to be synchronized on the same object. this can be different. If you want all the thread waiting on a object to be notify you havo to call notifyAll() instead of notify(). The notifyAll() should be put inside the finally block. Infact despite the return the finally block is alway executed
The notify() should be inside the finally block if you want it to work unconditionally, but you should really be using Thread.join() instead of wait(): then the thread being waited on doesn't have to do anything at all.
Answer is no. Unless you explicitly notify() in catch block before returning, the other thread will not wake up, You have to Al possible exceptions and in every case notify to your first thread, make sure that your first thread input is not dependent on second thread output otherwise you may phase some other problem in thread 1.
Started several worker threads , need to notify them to stop. Since some of the threads will sleep for a while before next round of working, need a way which can notify them even when they are sleeping.
If it was Windows programming I could use Event and wait functions. In Java I am doing this by using a CountDownLatch object which count is 1. It works but don't feel elegant, especially I have to check the count value to see if need to exit :
run(){
while(countDownLatch.count()>0){
//working
// ...
countDownLatch.wait(60,TimeUnit.SECONDS);
}
}
Semaphore is another choice, but also don't feel very right. I am wondering is there any better way to do this? Thank you.
Best approach is to interrupt() the worker thread.
Thread t = new Thread(new Runnable(){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
//do stuff
try{
Thread.sleep(TIME_TO_SLEEP);
}catch(InterruptedException e){
Thread.currentThread().interrupt(); //propagate interrupt
}
}
}
});
t.start();
And as long as you have a reference to t, all that is required to "stop" t is to invoke t.interrupt().
Use the builtin thread interruption framework. To stop a worker thread call workerThread.interrupt() this will cause certain methods (like Thread.sleep()) to throw an interrupted exception. If your threads don't call interruptable methods then you need to check the interrupted status.
In the worker thread:
run() {
try {
while(true) {
//do some work
Thread.sleep(60000);
}
}
catch(InterruptedException e) {
//told to stop working
}
}
Good way is to interrupt() threads, and inside thread make cycle like
try {
while (!Thread.interrupted()) {
...
}
} catch (InterruptedException e) {
// if interrupted in sleep
}
Keep in mind both cases when do interrupt:
if you sleep or wait then InterruptedException will be thrown;
in other cases interrupted flag will be set for the thread which you have to check yourself.
To have a pool of threads I would use the ExecutorService or a ScheduledExecutorService for delayed/periodic tasks.
When you want the workers to stop you can use
executorService.shutdown();
The other best approach would be to use interrupt( ) method.
E.g Here's how a thread uses this information to determine whether or not it should terminate :
public class TestAgain extends Thread {
// ...
// ...
public void run( ) {
while (!isInterrupted( )) {
// ...
}
}
}