What causes an java.lang.IllegalMonitorStateException - java

I'm trying to write a code which wants to make a write thread. When I want to run it, I got this exception. Each post that I saw about this topic didn't have the code same as mine. So can any one help me about my problem?
java.lang.IllegalMonitorStateException
The stacktrace is as below:
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at prj.McWThread.ReadPacket(McWThread.java:40)
at prj.McWThread.run(McWThread.java:73)
The part of code that makes this exception is :
public void run()
{
try{
while (true)
{
this.MyPkt = ReadPacket();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(MyPkt);
}
}
}
Readpacket method:
public MyPacket ReadPacket()
{
MyPacket m = new MyPacket();
System.out.println("ReadPacket");
try {
while (Buff.isEmpty()) {
wait();
}
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
if (! Buff.isEmpty()) {
m = (MyPacket) Buff.remove(0);
return m;
} else {
return m;
}
}

You need to synchonize your call to wait in your code. Two Options:
Declare your method as syncronised
public syncronized MyPacket ReadPacket()
use synchronized(this) before your call to wait.
The first one may not be advisable depending on your design and the work other threads need to carry out, if any.
For the second option, again, you need to be sure if you would want to use this as your monitor. You can create a Lock and use that instead.

The javadoc for Object.wait.
"The current thread must own this object's monitor." and "[throws] IllegalMonitorStateException - if the current thread is not the owner of the object's monitor."
You need to synchronize on the object you are going to call the wait on.
The code should look something like
synchronize(someobject){
someobject.wait();
}

Related

HowTo- thread stop

just a little question, i want to stiop the following thread, but i have no idea how i should do. Please help me. Googles help wasnt useful this time.
new Thread(){
public void run() {
while(!isInterrupted()){
try {
if (sock1!=null){
sock1.setTcpNoDelay(true);
if (btsar1.length > 0) {
dos1 = new DataOutputStream(sock1.getOutputStream());
bwrtr1 = new BufferedWriter(new OutputStreamWriter(
dos1), 300);
dos1.write(btsar1);
set1free = false;
Log.e("Communication", "written(1.1)");
Reader1.reader(4);}
}} catch (IOException e) {
e.printStackTrace();
}catch (NullPointerException e2){
e2.printStackTrace();
}
}
}}.start();
//.interrupt(); <-- or kinda that...
Can someone provide a good working thing, to stop this?
You just need a reference to your thread:
Thread t = new Thread(...);
Then you can interrupt it:
t.interrupt();
Thread t = new Thread(){
... // content unchanged
};
t.start();
.....
t.interrupt();
The best way to terminate a thread is to let it finish. So add a boolean flag in your while, and have method (or otherwise) expose it so it can be set to false. Then your thread would naturally exit after the interation has finished.
An idea: stop using anonymous threads!
Whenever you find yourself in a situation where your thread is doing something complicated, either create a separate class extending the thread, which can be used to control and monitor the behaviour, or use an abstract Future and a ThreadPool to do the work.
You will have an extremely unmaintainable and unextendable code if you keep using threads like this.
How to stop a thread gracefully?
bool keepWorking = true;
while(keepWorking) {
// keep working
}
synchronized void stopWork() {
keepWorking = false;
}
// in other thread
threadObj.stopWork();
Thread.interrupt method is for to stop a thread that waits for long periods (e.g., for input)
Take a look at this Article - How to Stop a Thread or a Task
example
public void stop() {
Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}

Java - Call wait() on an object and then allow object access to method

I have this method which takes a thread as a parameter. I want this method to be able to make a thread wait if there is not one waiting already and then wake up when another thread comes into the method so that the two of them can interact. I think I'm close but after I call wait() on the first thread no other threads can gain access to that method. Here is a minimalist version of my code:
// In the class 'Node'
public synchronized void trade(Thread thread)
{
if (!threadWaiting)
{
threadWaiting = true;
synchronized(thread)
{
try {
thread.wait();
} catch (InterruptedException e) {...}
}
}
}
I apologise for missing anything obvious, I've been looking around for an answer but I'm new to threading so I've no idea what to look for.
So my problem is that when another thread attempts to get into trade() they can't, the debugger just stops right there.
EDIT:
Here's some more clarification on what I'm asking. I'm afraid I wasn't too clear in my original post.
So I have one class called Node and another class called Bot. Bot extends thread so that it can be paused. At the start of the program multiple Bot objects are created and are then started, each Bot will then call the trade() method of the Node and pass itself to the method. If a Bot is the first in the method then I want its thread to wait on the Node until another Bot comes along (The waiting Bot will be stored in the Node), at which point the two Bots will interact.
Below is a clearer example of my method in pseudo code:
// Variable to hold the bot that is waiting.
private Bot waitingBot = null;
// Method belonging to Node.
public synchronized void trade(Bot currentBot)
{
if (waitingBot == null)
{
waitingBot = currentBot;
waitingBot.wait();
}
else
{
currentBot.interactWith(waitingBot);
waitingBot.notify();
waitingBot = null;
}
}
Sorry about the wording of my original post.
Your implementation has a flaw. You are taking lock on parameter passed which will be different for all Threads so they can't interact with wait notify.
EDIT: I am not sure what exactly your aim is but based on details this might help:
EDIT2: Added lock()
private final Lock lck = new ReentrantLock();
private final Condition cnd = lck.newCondition();
private final AtomicBoolean threadwaiting = new AtomicBoolean(false);
public synchronized void trade(Thread thread)
{
lck.lock();
try{
if(threadwaiting.get()){
cnd.signalAll();
threadwaiting.set(false);
//perform your task
}else{
cnd.await();
threadwaiting.set(true);
}
}
} finally {
lck.unlock()
}
}
EDIT:
Looking at your updated post , you should use cyclicbarrier with count 2 then that should solve it all for you.
This is a dead lock, because when you call thread.wait(); you release thread object lock. But this object lock on synchronized method remains, that's why no one else can enter it.
It's like loki's code, but improved
private final Lock lock = new ReentrantLock();
private final Condition cnd = lock.newCondition();
private final AtomicBoolean threadwaiting = new AtomicBoolean(false);
public void trade(Thread thread) {
lock.lock();
if (threadwaiting.get()) {
cnd.signalAll();
lock.unlock();
// perform your task of second thread
} else {
threadwaiting.set(true);
try {
cnd.await();
// perform your task of first thread
} catch (InterruptedException e) {
} finally {
threadwaiting.set(false);
lock.unlock();
}
}
}

Simple Threads run in series? (Second thread does not run until first thread stops)

I am starting two thread one after the other.
The first thread is reading in a loop from input and the other one check some condition in a loop to
sent an interrupt to the other.
The problem is that any thread of the two I start first it doesnt let the other stop.
If i start reading in never runs the other thread until it finishes and if I start the other thread is checking the condition in the loop and it wont move forward in code until the condition is true and gets out of the loop.
What is the correct way to do it?
Sample code below:
Thread 1)
public class InterruptionThread extends Thread {
public void run() {
while (condition not true) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (condition true) {
do some work
return;
}
}
}
Thread 2)
public class ReadingThread extends Thread{
public void run() {
int input;
while (true) {
try {
input = stdInput.read();
} catch (IOException e) {
e.printStackTrace();
return;
}
System.out.print((char) input);
}
}
}
This sounds like you are not starting the threads in a correct manner.
Use the start() method to start threads, not the run() method (which doesn't actually start a thread).
new InterruptionThread().start();
new ReadingThread().start();
I think your problem is of producer consumer problem type.
So would suggest you to use BlockingQueue.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
Also instead of directly handling threads; it will be easy if you use Executor Framework; this way thread management will become pretty easy.

Synchronisation on java.io.File Object

Is it good to use synchronised on java.io.File Object. When you want to alternatively read and write that File Object using two threads: one for reading and one for writing.
public class PrintChar {
File fileObj;
public void read() {
while (true) {
synchronized (this) {
readFile();
notifyAll();
try {
wait();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()
+ " throws Exception");
e.printStackTrace();
}
}
}
}
public void write(String temp) {
while (true) {
synchronized (this) {
writeFile(temp);
notifyAll();
try {
wait();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()
+ " throws Exception");
e.printStackTrace();
}
}
}
}
public void setFileObj(File fileObj) {
this.fileObj = fileObj;
}
public void readFile() {
InputStream inputStream;
try {
inputStream = new FileInputStream(fileObj);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(inputStream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println(strLine);
}
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void writeFile(String temp) {
BufferedWriter bw;
try {
bw = new BufferedWriter(new FileWriter(fileObj, true));
bw.write(temp);
bw.newLine();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
final PrintChar p = new PrintChar();
p.setFileObj(new File("C:\\sunny.txt"));
Thread readingThread = new Thread(new Runnable() {
#Override
public void run() {
p.read();
}
});
Thread writingThread = new Thread(new Runnable() {
#Override
public void run() {
p.write("hello");
}
});
Thread Randomizer = new Thread(new Runnable() {
#Override
public void run() {
while (true)
try {
Thread.sleep(500000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()
+ " throws Exception");
e.printStackTrace();
}
}
});
readingThread.start();
writingThread.start();
Randomizer.start();
}
}
In the code above I have used Synchronised(this), Can i use Synchronise(fileObj)??
One More solution I have got from one of my professors is to encapsulate the read and write in objects and push them in a fifo after every operation, if anybody elaborate on this
Edit:
Now that you have added your code, you can lock on fileObj but only if it is not changed. I would move it to the constructor and make it final to make sure that someone doesn't call setFileObj inappropriately. Either that or throw an exception if this.fileObj is not null.
Couple other comments:
Don't use notifyAll() unless you really need to notify multiple threads.
If you catch InterruptedException, I'd quit the thread instead of looping. Always make good decisions around catching InterruptedException and don't just print and loop.
Your in.close(); should be in a finally block.
You can lock on any object you want as long as both threads are locking on the same constant object. It is typical to use a private final object for example:
private final File sharedFile = new File(...);
// reader
synchronized (sharedFile) {
// read from file
}
...
// writer
synchronized (sharedFile) {
// write to file
}
What you can't do is lock on two different File objects, even if they both point to the same file. The following will not work for example:
private static final String SHARED_FILE_NAME = "/tmp/some-file";
// reader
File readFile = new File(SHARED_FILE_NAME);
synchronized (readFile) {
...
}
// writer
File writeFile = new File(SHARED_FILE_NAME);
synchronized (writeFile) {
...
}
Also, just because you are locking on the same File object does not mean that the reading and writing code will work between the threads. You will need to make sure that in the writer that all updates are flushed in the synchronized block. In the reader you probably do not want to use buffered streams otherwise you will have stale data.
In general, locking across I/O is not a great idea. It's better to construct your program such that you guarantee by design that usually a given section of the file is not being concurrently written and read, and only lock if you absolutely must mediate between reads and writes of a given piece of the file.
Usually not. There are much better ways: Use a ReentrantLock
This class already offers the "lock for reading/writing" metaphor. It also correctly handles the case that many threads can read at the same time but only one thread can write.
As other people already mentioned, locking will only work if all threads use the same File instance.
Make sure you flush the output buffers after each write; this will cost some performance but otherwise, you'll get stale reads (read thread won't find data that you expect to be there).
If you want to simplify the code, add a third thread which accepts commands from the other two. The commands are READ and WRITE. Put the commands in a queue and let the 3rd thread wait for entries in the queue. Each command should have a callback method (like success()) which the 3rd thread will call when the command has been executed.
This way, you don't need any locking at all. The code for each thread will be much more simple and easy to test.
[EDIT] Answer based on your code: It would work in your case because everyone uses the same instance of fileObj but it would mix several things into one field. People reading your code would expect the file object to be just the path to the file to read. So the solution would violate the principle of least astonishment.
If you'd argue that it would save memory, then I'd reply with "premature optimization".
Try to find a solution which clearly communicates your intent. "Clever" coding is good for your ego but that's about the only positive thing that one can say about it (and it's not good for your ego to learn what people will say about you after they see your "clever" code for the first time...) ;-)
Queueing off read/write objects to one thread that then performs the operation is a valid approach to something, but I'm not sure what.
Wha it would not do, for example, is to enforce read/write/read/write order as you specified in your earlier question. There is nothing to stop the read thread queueing up 100 read requests.
That could be prevented by making the thread that submits an object wait on it until it is signaled by the read/write thread, but this seems a very complex way of just enforcing read/write order, (assuming that's what you still want).
I'm getting to the state now where I'm not sure what it is you need/want.

IllegalMonitorStateException - CyclicBarrier

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.

Categories