Why does this method throw an IllegalMonitorStateException? - java

public static synchronized void main(String[] args) throws InterruptedException {
Thread t = new Thread();
t.start();
System.out.print("X");
t.wait(10000);
System.out.print("Y");
}
What is the problem with this method?
How can I avoid such problems from now on?

There are a couple of problems with this code. I suspect you're trying to write something like this:
public static synchronized void main(String[] args) throws InterruptedException {
System.out.print("X");
Thread.sleep(10000);
System.out.print("Y");
}
The Thread.sleep() method will suspend the current thread for the specified interval. Object.wait() is something else entirely and it's unlikely that that's what you want.
You can see how I've eliminated the thread t. If you really want to create a separate thread and have the printouts produced on that thread then you need to give the thread something to do. The easiest way to do that is to override the thread's run() method and have the thread code there:
public static synchronized void main(String[] args) {
Thread t = new Thread() {
public void run() {
System.out.print("X");
try { Thread.sleep(10000); } catch (InterruptedException e) { }
System.out.print("Y");
}
};
t.start();
}
As written your original code was in fact creating a thread with no thread body, so when you call t.start() the empty thread would simply start up in the background and then immediately die.
Note that I had to add a try/catch clause for InterruptedException now that the sleep call has migrated to inside the thread. run() isn't allowed to throw exceptions so now, unfortunately, we have to catch and ignore the exception.
Another way to write this would be to do some of the work in the thread t and the rest of the work in your main thread. Here's an example of how you could split apart the work into two threads:
public static synchronized void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
System.out.print("X");
try { Thread.sleep(10000); } catch (InterruptedException e) { }
}
};
t.start();
t.join();
System.out.print("Y");
}
When this calls t.join() it will wait for the thread to finish executing, which will take 10 seconds since it's sleeping. Once the thread is finished then the join() method will return and allow the main thread to continue. The end result will appear the same to the user: the program will print X, pause for 10 seconds, and then print Y.

Well, John's suggestions will do the thing. But you might still feel blur regarding the exception occurred. For that I would like you to read the documentation of Object.wait() method, and of IllegalMonitorStateException.
After reading those, a question might come to your mind that, what the hell is Object's monitor. So here it is from wikibooks,
Each object has an 'Object monitor'. Basically it is a
'semaphore', indicating if a critical
section code is being executed by a
thread or not. Before a critical
section can be executed, the Thread
must obtain an 'Object monitor'. Only
one Thread at a time can own that
object's monitor.

Related

How do we test synchronization code?

Recently I am working on a piece of code involving synchronization and struggling on how to test it. To get into the problem, we can consider we are writing a unit test for a CountDownLatch:
CountDownLatch l = new CountDownLatch(1);
new Thread() {
#Override
void run() {
l.await();
System.out.println("good!");
}
}.start();
Thread.sleep(1000); // wait for thread to run
if (the thread is alive)
l.countDown();
else
System.out.println("bad!");
So the problem is, there is no guarantee that the sleep for 1 second would be enough in all cases in all machines. So my goal is to eliminate this type of sleeping code to expect a certain state when testing synchronization, but soon realize it starts to become halting problem.
My current solution would be to query the state of the thread:
Thread t = ...
t.start();
if (t.getState() == Thread.State.WAITING) {
l.countDown();
assert(t.getState() == Thread.State.RUNNABLE); // or running or terminated
}
my questions are:
would that work? i.e. would the state of the thread will be toggled atomically at the moment, in this case, a count down latch reach a wakeup condition?(the doc says nothing about the change timing of the state)
do you have better suggestions?
Looking into your example I have a feeling that you're using countdown latch upside-down. Why can't you do something like that:
#Test
public void testThreads() throws Exception {
CountDownLatch l = new CountDownLatch(1);
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Parallel thread is doing something.");
try {
// instead of this sleep you put your logic that you want to be executed.
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
l.countDown();
}
}).start();
System.out.println("Main thread is waiting for parallel thread");
l.await();
System.out.println("Done.");
}
Please, correct me if I misunderstand your problem.
But generally speaking, I agree with one of the comments below your post that you should probably not test multithreading with unit tests.

Java: calling a method from the main thread by signaling in some way from another thread

I have an application with 2 threads (the main and another thread t1) which share a volatile variable myVar. Any ideas on how to make the main thread to call a method myMethod by signaling in some way from t1 ?
I implemented it by using ChangeListener and myMethod is called when myVar changes, BUT the method is called from t1, and not from the main thread (note: I need to call this method from the main thread because this is a call to a JavaScript code from Java, so for a security reason only the main thread can do so). Thanks in advance.
You would have to have your main thread spin in a loop on some scalar, I would recommend one of the Atomics that java provides (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html), but you could use volatile if you wanted for this I think.
Each thread can only run sequentially - it's just the way computing works. The way you will handle this, is when the main thread spins in some sort of loop, you eventually check to see if this scalar of yours has been set, and when it has, you want unset the variable and execute your JavaScript. In this particular piece of your code, I think the Atomics have an advantage over the volatile with the use of the compareAndSet operations because using volatile can mess you up a bit between threads if you are trying to check the value in one operation and then set it again in another operation which gives the other thread enough time to set it again - meaning you may miss a call to your JS because the other thread set the variable between the main thread checking it and setting it (although the use of volatile vs Atomics may be interpreted as my opinion).
//main thread
AtomicBoolean foo = new AtomicBoolean(false);
while (...somecondition...){
if(foo.compareAndSet(true, false)){
//execute JS
}
//do some other work
}
and in your T1 thread, just call foo.set(true).
If you expect main to call your JS for each time T1 sets foo to true, then you will have to block in T1 until main has unset foo, or use an AtomicInteger to count how many times T1 has set foo - depending on your needs.
Since both tread sharing the same instance of myVar, you can make both thread to synchronize on the shared variable. Have main to wait on myVar notification before executing myMethod. Later, t1 can notify through variable myVar, and the waiting thread can continue and proceed with the method call.
The following snippet fully demonstrated the idea
public class MainPlay {
public static void main(String[] args) {
MainPlay mp = new MainPlay();
mp.execute();
}
public void execute() {
Thread main = new Thread(mainRunnable, "main");
Thread t1 = new Thread(t1Runnable, "t1");
main.start();
t1.start();
}
public Object myVar = new Object();
public void myMethod() {
System.out.println("MyMethodInfoked.");
}
public Runnable t1Runnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[t1] sleep for 1 sec");
Thread.sleep(1000);
System.out.println("[t1] Notifying myVar so Main can invoke myMethod");
myVar.notify();
} catch (InterruptedException e) {
// interupted.
}
}
}
};
public Runnable mainRunnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[main] Waiting for t1 to notify...");
myVar.wait();
} catch (InterruptedException e) {
// interrupted.
}
System.out.println("[main] executing main method");
myMethod();
}
}
};
}
And the output is
[main] Waiting for t1 to notify...
[t1] sleep for 1 sec
[t1] Notifying sharedObject so Main can invoke myMethod
[main] executing main method
MyMethodInfoked.
You could use wait/notify blocks to prevent the main thread from continuing until signalled to do so.
static Main main = // ...
static boolean signal = false;
// t1:
// Do work
signal = true;
synchronized (main) {
main.notify();
}
// main:
synchronized (main) {
while (!signal) {
main.wait();
}
}
myMethod();
In case the main thread has nothing else to do, the approach proposed by #searchengine27 results in unnecessary processor load generated by this thread.
So instead going with some AtomicXXX class it would be better to use some of the blocking queues which allow writing of data from one thread (with put()) and consumption of that data by the other. The main queue would block (by calling take() method) if such a queue is empty not using any CPU resources.

What is wrong with it?

I've seen a lot of example for wait and notify, but still I have a problem.
public class Main(){
public static void main(String args[]) throws Exception {
MyThread s = new MyThread();
s.start();
}
}
class MyThread extends Thread {
public void run() {
k();
}
public synchronized void k() {
System.out.println("before wait");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("do something after wait");
}
public synchronized void m() {
for (int i=0;i<6;i++)
System.out.println(i);
notify();
}
}
The only output I get when run the program is: "before wait".
The thread you create in main invokes MyThread#k() which goes into a wait. At that point, that thread will do nothing else until it is awakened or interrupted. But the only place in your code where it could possibly be awakened is the notify in MyThread#m(). Since nothing in your program calls that method, the thread can never be awoken.
What you probably want is to add a call to s.m() right after s.start() in your main program. That way your main thread will execute the notify that's needed to wake up your thread.
Unfortunately, that's very unlikely to work. The problem is that s.start() causes your created thread to become ready to run, but it doesn't necessarily run immediately. It could well happen that your call to s.m() will complete before the created thread does anything. And then you'll still have exactly the same result as before, except that you'll see the integers 0..6 printed out before before wait. The notify will do nothing, because the child thread has not yet performed its wait. (And by the way, since both MyThread#k() and MyThread#m() are both synchronized, increasing your loop limit in MyThread#m() won't change a thing... the child thread won't be able to enter MyThread#k() while MyThread#m() is running. You could improve that by putting the notify in a sycnchronized block rather than making all of MyThread#m() synchronized.)
You can try to get around this by adding Thread.sleep(1000) before s.m() in your main program. That will almost certainly work because your main thread will yield execution, giving your JVM the opportunity to schedule the child thread for some useful work. By the time the main thread wakes out of its sleep and performs its s.m() call, the child will probably have executed its wait and you will then see your do something after wait message.
But that's still pretty crummy, because it still depends on scheduling events that you don't really have any control over. There's still no guarantee that the wait will happen before the notify.
This is why when using wait/notify you should generally arrange for there to be some sort of reliable test as to whether whatever you're waiting to be done has actually occurred. This should be a condition that, once it turns turns true, will remain true at least until the test has been subsequently performed. Then your typical wait loop looks something like this:
while (!isDone()) {
synchronized(monitorObject) {
try {
monitorObject.wait();
} catch (InterruptedException e) {
}
}
}
Putting the whole thing in a loop takes care of premature waking, e.g. due to InterruptedException.
If the required work has already occurred by the time this code is executed, no wait occurs, and the notify executed by the code that did the work was a no-op. Otherwise, this code waits, and the code completing the work will eventually do a notify which will wake this code up as required. Of course, it's critical that, at the time the notify is performed, the wait condition (isDone() above) be true and remain true at least until tested.
Here's a corrected version of your code that incorporates a proper wait loop. If you comment out the Thread.sleep() call, you will likely not see the waiting message, because the work will complete before the wait loop even starts. With the sleep included, you'll probably see the waiting message. But either way, the program will work properly.
public static void main(String[] argv) throws Exception {
MyThread s = new MyThread();
s.start();
Thread.sleep(1000);
s.m();
}
class MyThread extends Thread {
#Override
public void run() {
k();
}
private boolean done = false;
public void k() {
System.out.println("before wait");
while (!done) {
System.out.println("waiting");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
System.out.println("do something after wait");
}
public void m() {
for (int i = 0; i < 6; i++) {
System.out.println(i);
}
synchronized (this) {
done = true;
notify();
}
}
}
The problem is, that you're not calling your m method, so notify is never called, so your thread sleeps forever. You could call it in main, after the start, using s.m():
MyThread s = new MyThread();
s.start();
s.m();
Maybe you should sleep for a little time before calling the m method, as it could run sooner than k in the thread:
s.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// nothing to do
}
s.m();
Not closely related to the question, but a throws declaration in main is not very advisable, even a generated printStackTrace is better than throwing the exception away.

Two thread which invokes wait and notify

The code I've witten doesn't work as I expected.
static Integer sync = 1;
static void m() throws Exception {
synchronized (sync) {
System.err.println("First");
sync.notify();
sync.wait(1000L);
System.err.println("Second");
System.err.println("Third");
}
}
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
#Override
public void run() {
try {
m();
} catch (Exception ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Runnable t = new Runnable() {
#Override
public void run() {
try {
m();
} catch (Exception ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Thread th1 = new Thread(r);
Thread th2 = new Thread(t);
th1.run();
th2.run();
}
We have two threads which execute m()'s syncjronized statement. When the first thread executes one and come across the wait() it'll be added to the wait set. After this, the second thread is starting to execute the synchronized statement, and perform notify(). Since the output must be
First
First
....
But actually it is
First
Second
Third
First
Second
Third
Why?
First of all, your program is not creating any threads. You must call th1.start() and th2.start() to create threads.
t.start() is the method that the library provides for your code to call when you want to start a thread. run() is the method that you provide for the library to call in the new thread. Your run() method defines what the thread will do. IMO, run() was a really misleading name.
Second, notify() and wait() don't do what it looks like you think they will do. In particular, sync.notify() will not do anything at all if there are no other threads currently in sync.wait().
The correct way to use notify() and wait() is, one thread does this:
synchronized(lock) {
while (! someCondition()) {
lock.wait()
}
doSomethingThatRequiresSomeConditionToBeTrue();
}
The other thread does this
synchronized(lock) {
doSomethingThatMakesSomeConditionTrue();
lock.notify();
}
When you use this pattern, no thread should ever change the result of someCondition() except from inside a synchronized(lock) block.
Firstly, To actually create new threads please use
th1.start()
th2.start()
inplace of run() , which is just a regular method call on the thread object.
Secondly, it is possible that the second thread 'th2' did not start running by the time 1000 ms was fninshed , so the first thread finished wait(1000) and executed the remainging lines of code.
if you want the output like so :
first
first
second
third
second
third
then remove the time interval for wait() which will make the threads wait until notified.
as in :
static void m() throws Exception {
synchronized (sync) {
System.err.println("First");
sync.notify();
sync.wait();
System.err.println("Second");
System.err.println("Third");
}
}
Use .start() instead of run() to add runables to the queue instead of running them immediately
Documentation says that wait with timeout waits for any notify on this object or the timeout. In your case when runnables are being executed one by one it goes:
r: First
r: waits 1000ms and try to get lock
r: it already have access to lock object (exactly this code got lock) so continue
r: Second
r: Third
t: First, and so on ...
PS. calling run() and not setting timeout will cause deadlock on t's wait, cause it already has the object but will wait never be notified about it.
Hope this helps.

Thread and static variables

Trying to wrap my head around this code. When I run this - the output will be Roger. Isn't msg a static variable and at a class level thus should print Moore?
EDIT : I've allowed a sleep too allow the child thread to run its course. It also prints printing... Still No Change
public class Test2 {
private static String msg = "Roger";
static {
new Thread(new Runnable() {
public void run() {
System.out.println("printing..");
msg += "Moore";
}
}).start();
}
static {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
public static void main(String argv[]) {
System.out.println(msg);
}
}
Trying to wrap my head around this code. When I run this - the output will be Roger. Isn't msg a static variable and at a class level thus should print Moore?
As others have pointed out, this is a race condition but it's more complicated then this simple answer.
EDIT : I've allowed a sleep too allow the child thread to run its course. It also prints printing... Still No Change
When a class is initialized, the static code is executed in the thread that accesses the class first – in this case the main thread. All other threads have to wait for this initialization to complete before they can access the class. This means that the background thread actually stops and waits for the class initialization to complete before it can execute msg += "Moore";. Then it is a race to see whether the msg is assigned to "Roger" and the background thread can append to it before main prints it. Even with the msg field being volatile, the race still exists. You can get a glimpse into the complexities of the process from the JLS section 12.4.2 on Detailed Initialization Procedure.
So what is happening is approximately:
The main thread initializes the Test2 class.
The msg is initialized first because it comes before the static blocks.
First static block is executed which forks the background thread.
Second static block is executed which does the sleep() blocking the initializing thread.
Background thread starts to run (could be before the previous step). It goes to update msg but the class is locked since the main thread is sleeping and hasn't completed with the class initialization. The background thread has to wait.
The main thread wakes up and finishes the initialization.
This releases the block on the class which allows the background thread to continue.
At the same time as the previous step, main is called and it is a race condition to see if the msg can be updated before it is printed out.
In general, forking background threads in static methods like this is extremely frowned upon. Putting a sleep in a static block is obviously not recommended as well.
The main method will not be called till all the static initializers in your class are done. So it will always wait till the static inits are done. Even if there is a sleep in it.
Additionaly static initialization is thread safe, so your forked thread cannot access the variable, till the static init blocks are done.
It's a race condition. There's no guarantee when the Runnable will have executed.
EDIT: This answers responds to the original posted question, in which no delay was present in the static initializer. This was leading to a simple race condition between the main thread reading the static member and the spawned thread updating it.
Rather than wait a little bit, and hope the other thread runs, you can guarentee it with some synchronization:
public class Test {
private static String msg = "Roger";
private static volatile boolean done = false;
private static final Object lock = new Object();
static {
new Thread(new Runnable() {
public void run() {
synchronized(lock)
{
lock.notify();
System.out.println("printing..");
msg += "Moore";
done=true;
}
}
}).start();
}
public static void main(String argv[]) {
synchronized(lock)
{
while(!done)
{
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.println(msg);
}
}
If the main thread aquires the lock first, then it will msg.wait. It will not continue until notify is called(actually, it continues when the synchronized block containing notify finishes). If the new thread aquires the lock first, then the main thread will have to wait at the start of it's synchronization block. Once it gets in, done will be true. It will not wait, and go straight through.

Categories