Why Iam getting Illeagal Monitor exception [duplicate] - java

This question already has answers here:
Java Wait and Notify: IllegalMonitorStateException
(2 answers)
Closed 4 years ago.
I am getting an illegal monitor exception. I googled it but nothing clarifies what i am doing wrong.
From this normalclass I create an object for other class and give the object to thread and synchronize the thread. Why am I getting this exception?
/* synchronize the thread object a */
/* here iam calling wait on thread as it need to complete run */
public class Normalclass
{
public static void main(String[] args)
{
NormalThread k = new NormalThread();
Thread a =new Thread(k);
a.setName("test");
a.start();
synchronized(a){
try{
a.wait();
} catch(InterruptedException e){
System.out.println("exception");
}
}
}
}
public class NormalThread implements Runnable
{
public void run()
{
for(int i=0;i<=100;i++)
{
System.out.println(i);
}
notify();
}
}
/* here iam notifying after the run for loop completed*/
// Iam getting illegal monitor exception

In your example notify() is called on NormalThread k object while wait() is called on Thread a object. You should call these methods on the same object for the signal to propagate.
You could fix your by grabbing the monitor for k to avoid the exception by using:
synchronized(this) {
notify();
}
but frankly the example makes little sense. Normally what you try to accomplish is done with Thread.join(). As per the method javadoc:
Waits for this thread to die.
Thread a = new Thread(k);
a.start();
a.join();

Related

Java - Synchronizing and Starting Threads [duplicate]

This question already has answers here:
Execution of new thread inside a synchronized block
(2 answers)
Closed 4 years ago.
I was wondering, if I make a method synchronized and then start a Thread in this method when will other Threads be able to use the method?
synchronized void someMethod() {
//Do stuff.
new Thread(new Runnable() {
public void run() {
//Do more stuff.
}
}).start();
}
That is, will other Threads be able to access someMethod when the Thread calling someMethodexits it or will the newly created Threadhave to finish as well?
When the Thread calling someMethod exits it, it won't wait for new Thread to finish.
Whenever the monitor on object instance to which someMethod() belongs is released. This should be after the call to Thread.start() in your code. There is no magic here, standard rules for synchronized apply.
Synchronized method means only one thread is able to access any of the method execution at once. That's including declaring and performing a new instance, also new thread instance as in your example:
new Thread(new Runnable() {
public void run() {
//Do more stuff.
}
}).start();
The thread which is next to be triggered would declare a new and different instance, and due the fact you haven't stored the former declared threads anywhere, it wouldn't be accessable.
It could be accessed with some modifications:
synchronized void someMethod(int id, HashMap threadsMap) {
//Do stuff.
threadsMap.set(id, new Thread(new Runnable() {
public void run() {
//Do more stuff.
}
}));
threadsMap.get(id).start();
}
This would allow you to access each thread by its id

Java thread join method calls wait on which object?

I'm new to Java multi threading and little confused with how Java join and wait works.
I have the following example
public class Main {
private static int counter;
static class RunnableThread implements Runnable {
private static final String PREFIX = "RT-";
public RunnableThread() {
}
#Override
public void run() {
counter++;
System.out.println(PREFIX+counter);
try {
Thread.sleep(50000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread rt = new Thread(new RunnableThread());
//Thread tt = new TradThread();
rt.start();
//tt.start();
try {
rt.wait();
} catch (InterruptedException e1) {
System.out.println("Main thread wait is interrupted");
e1.printStackTrace();
}
System.out.println("MT-"+counter);
}
}
It throws IllegalMonitorStateException as the main thread doesn't hold any monitor. Now in the same code if I change rt.wait() to rt.join() it works.
When I see how join is implemented it looks like it calls the wait() method. Now how is the call to wait from inside the join valid?
I would assume The Main thread when it calls rt.join() the code in the join method is being executed by the Main thread itself.
Please help me to understand this.
Thanks
Thread.join() and Object.wait() are very different.
t.join()
Join current thread where you are behind thread t. So, current thread will not run until thread t finishes its work.
o.wait()
Release the lock of object o and pause current thread. So, current thread will not run until it obtains the lock of object o again by o.notify() or o.notifyAll() from other thread.
Note: you must have obtained the lock of object o before invoking this method.
Technically, in the join code, we have:
wait(0);
...
wait(delay);
in this case, this is the same as calling this.wait(). So to answer the question, the wait function being called is the object referenced by rt wait method.

Running many thread and Stop thread on Exception

I have a Thread (implements Runnable) from many branch officer call that thread with their branch code. I set up a name of their thread with branch code.
The problems are...
When an exception occurred in running thread - I can't stop that. And when try to make another thread with any name "ExceptionInInitializerError" or "OutOfMemoryError: Java heap space" comes
"OutOfMemoryError: Java heap space" exception comes When 2 or more thread running at a time.
public MyRunnerClass {
//This method called from many branch with their branch Code
public void executeBranchProcess(String branchCode){
Thread t = new Thread(new Exporter(branchCode);
t.setName(branchCode);
t.start();
}
}
Thread Class here
public class Exporter implements Runnable{
private String branchCode;
public Exporter(String branchCode){
this.branchCode = branchCode;
}
#Override
public void run() {
try {
exportCorner();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void exportCorner() throws InterruptedException{
try{
//Some Process
}catch(Exception e){
// I want to close running thread here
// I am using closeThread(this.branchCode), but not working
}
}
static void closeThread(String branchCode) throws InterruptedException {
Thread thread = null;
for (Thread t : Thread.getAllStackTraces().keySet()) {
if (t.getName().equals(branchCode))
thread = t;
}
if (thread != null) {
thread.interrupt();
thread.join();
}
}
}
You face multiple problems here:
You cannot join a thread in itself. Thread.join() waits until the thread dies. But if you call it from the thread you want to stop, it just waits forever.
To stop a thread you simply have to return from its run() method. In your case, just add return in your catch clause instead of calling closeThread().
It seems that you have some memory problems. Either whatever you do in exportCorner() uses alot of memory or you create to many threads at once. As Andy Turner has mentioned in the comments, it might be usefull to use an ExecutorService to handle your Runnables. This may help you managing your threads and ensure a limited thread count.

Why Java throw java.lang.IllegalMonitorStateException when I invoke wait() in static way synchronized block?

I do not understand why Java throw exception from subject in this code. Could somebody explain me it?
class Wait implements Runnable
{
public void run() {
synchronized (Object.class) {
try {
while(true) {
System.out.println("Before wait()");
wait();
System.out.println("After wait()");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ObjectMethodInConcurency
{
public static void main(String[] args) {
Wait w = new Wait();
(new Thread(w)).start();
}
}
Use synchronized (this) { instead of synchronized (Object.class) in your class
EDIT
Reasoning behind the IllegalMonitorException in above code
In Java using synchronized keyword is a way to create and obtain a monitor object which will be used as lock to execute corresponding code block.
In the above code that monitor is "Object.class".
And wait() method tells the current thread to wait until it is notifyed and you have to invoke wait() on the monitor object which owns the lock.
So the way to invoke wait() method is like below otherwise you will get IllegalMonitorException.
synchronized(monitor){
monitor.wait();
}
So for your example you can either use "Object.class.wait()" or change the monitor to this since you are calling wait() method on the current instance

Synchronize thread and a method with an object?

I have a method and a thread which I'd like to run in the following order: First the method should do something with an object, and then the thread should do something with the object. They share the same object. I have to synchronize them, but I am just meeting with Threads. How can I do that?
private synchronized method()
{
//do something with an object (a field)
}
Runnable ObjectUpdater = new Runnable()
{
//do something with the object after the method has finished
}
My code, that somehow manages to freeze my Main thread (where the method is)
My thread code:
private Runnable something = new Runnable(){
synchronized (this){
while (flag == false)
{ try {wait();)
catch (IntExc ie) {e.printStackTrace...}
}
//here it does its thing
}
setFlag(false);
}
My method code (part of the main thread)
private void Method()
{
//do its thing
setFlag(true);
notifyAll();
}
To me that is simple questions
" you said that I do not know which is
going to access the object first - the
separate ObjectUpdater thread, or the
main thread (with the method). If the
separate thread accesses it before the
main thread, that is bad and I don't
want this to happen"
if you want the main thread method to call first then the objectUpdater thread , have a flag to know whether the method is visited first by main thread ,if it is updater then call wait to this thread , once main finishes it call notify which will run separator thread,
to know which thread is main thread or updater thread , set a name to the thread while creating it. and get the name as Thread.currentThread().getName().
Use the Semaphore class to allow access to the object.
public class Main
{
public static void main (String[] args) {
final Obj obj = new Obj();
final Semaphore semaphore = new Semaphore(0);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
semaphore.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
return;
}
obj.doSomething();
}
});
t.setName("test");
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
obj.doSomething();
semaphore.release();
}
}
class Obj {
public void doSomething() {
System.out.println("something done by " + Thread.currentThread());
}
}
Apart from synchronizing on the object, you could call the method as first statement in the new thread, or you could start the new thread at the end of the method.
It is hard to say what is the best approach in your case, maybe you can give us some more details on the how and what?
Update
In answer to your code (for some reason I cannot add another comment...)
Is the method called from a synchronized(this) block? If not the notifyAll() should be in a synchronized block. Also, can you update the code to show where/how your main thread interacts with the method and the object?
I think better approach would be to call the method using which you want to perform something with an object, and then declare the thread which would do something with an object.

Categories

Resources