This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Side effects of throwing an exception inside a synchronized clause?
I am wondering if synchronized is exception-safe? Say, an uncaught exception happens within the synchronized block, will the lock be released?
When in doubt, check the Java Language Specification. In section 17.1 you'll find:
If execution of the method's body is ever completed, either normally
or abruptly, an unlock action is automatically performed on that same
monitor.
Synchronize is neither thread-safe nor non-thread-safe. The way you phrased the question just doesn't make sense.
In case of an exception the lock will be released.
Only a System.exit prevents a block exiting normally. It means finally blocks are not called and locks are not released.
private static final Object lock = new Object();
public static void main(String... args) throws ParseException {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Locking");
synchronized (lock) {
System.out.println("Locked");
}
}
}));
synchronized (lock) {
System.exit(0);
}
}
prints
Locking
and hangs. :|
Yes, it will. The major point of the synchronize keyword is to make multi-threaded coding easier.
Yes the object will become unlocked if an exception is thrown and not caught.
You can find some code examples here.
Yes it will.
As a side note, the try-finally construct will ensure the finally block will be executed when the try exits
try {
someFunctionThatMayThrow();
} finally {
willAlwaysBeExecuted();
}
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've read this topic, and this blog article about try with resources locks, as the question popped in my head.
But actually, what I'd rather like would be a try with lock, I mean without lock instantiation. It would release us from the verbose
lock.lock();
try {
//Do some synchronized actions throwing Exception
} finally {
//unlock even if Exception is thrown
lock.unlock();
}
Would rather look like :
? implements Unlockable lock ;
...
try(lock) //implicitly calls lock.lock()
{
//Do some synchronized actions throwing Exception
} //implicitly calls finally{lock.unlock();}
So it would not be a TWR, but just some boilerplate cleaning.
Do you have any technical reasons to suggest describing why this would not be a reasonable idea?
EDIT : to clarify the difference between what I propose and a simple synchronized(lock){} block, check this snippet :
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
public static void main(String[] args) {
ReentrantLock locker =new ReentrantLock();
Condition condition = locker.newCondition();
Thread t1 = new Thread("Thread1") {
#Override
public void run(){
synchronized(locker){
try {
condition.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Thread1 finished");
}
}
} ;
Thread t2 = new Thread("Thread2") {
#Override
public void run(){
synchronized(locker){
Thread.yield();
condition.signal();
System.out.println("blabla2");
}
}
} ;
t1.start();
t2.start();
}
}
Execution will result in a IllegalMonitorStateException, so lock() and unlock() methods are not implicitly called within synchronized block.
If you had to deal with a simple case like that, where the pattern of locking/unlocking was limited to a narrow scope like this, you probably don't want to use the more complicated Lock class and probably should just be using the synchronized keyword, instead. That being said, if for some reason you needed this with the more complicated Lock object, it should be relatively straight-forward to create a wrapper around Lock that implements the AutoCloseable interface to be able to do just that. Example:
class AutoUnlock implements AutoCloseable {
private final Lock lock;
public static AutoUnlock lock(Lock lock) {
lock.lock();
return new AutoUnlock(lock);
}
public static AutoUnlock tryLock(Lock lock) {
if (!lock.tryLock()) {
throw new LockNotAcquiredException();
}
return new AutoUnlock(lock);
}
#Override
public void close() {
lock.unlock();
}
private AutoUnlock(Lock lock) {
this.lock = lock;
}
}
With a wrapper like the above, you could then do:
try (AutoUnlock autoUnlock = AutoUnlock.lock(lock)) {
// ... do whatever that requires the lock ...
}
That being said, the Lock class is typically used for very complicated locking scenarios where this wouldn't be particularly useful. For example, Lock objects may be locked in one function in a class and later unlocked in another function (e.g. locking a row in a database in response to an incoming remote procedure call, and then unlocking that row in response to a later RPC), and thus having such a wrapper or making a Lock AutoCloseable, itself, would be of limited use for the way it is actually used. For more simple scenarios, it's more common to just use an existing concurrent datastructure or use synchronized.
This answer serves to explain the behavior of your edit. The purpose of synchronized is to lock the monitor of the given object when the thread enters the block (waiting if it isn't available) and releasing it when the thread exits the block.
Lock is a higher level abstraction.
Lock implementations provide more extensive locking operations than
can be obtained using synchronized methods and statements.
You can use it to lock across method boundaries. synchronized is not able to do this so a Lock cannot be implemented solely with synchronized and no implementation I've ever seen uses it. Instead, they use other patterns, like compare and swap. They use this to set a state atomically within a Lock object which marks a certain thread as the owner of the lock.
In your code snippet, you try to invoke
condition.signal();
in a thread which does not own the Lock from which the condition was created. The javadoc states
An implementation may (and typically does) require that the current
thread hold the lock associated with this Condition when this method
is called. Implementations must document this precondition and any
actions taken if the lock is not held. Typically, an exception such as
IllegalMonitorStateException will be thrown.
That's what happened here.
Executing
synchronized (lock) {}
makes the current thread lock (and then release) the monitor on the object referenced by lock. Executing
lock.lock();
makes the current thread set some state within the object referenced by lock which identifies it as the owner.
This question already has answers here:
Threads - Why a Lock has to be followed by try and finally
(6 answers)
Closed 8 years ago.
I'm not sure whether the following implementation is correct. My reason is that if the current thread is interrupted while it is waiting to be signaled, the finally block will be called, but because it's not holding the lock, an IllegalMonitorStateException will be thrown. Did I implement a try-finally block correctly in this case or rather should one be implemented?
public void acquire() throws InterruptedException {
try {
lock.lockInterruptibly();
while (permits == 0) {
condition.await();
}
permits--;
}
finally {
lock.unlock();
}
}
Not sure that I understand problem correctly, but you should try-finally only after the resource is allocated
public void acquire() throws InterruptedException {
lock.lockInterruptibly(); // allocate resource before try
try {
while (permits == 0) {
condition.await();
}
permits--;
}
finally {
lock.unlock();
}
}
I do not know why do all schools, e.g. Sun's official page on finally, advise allocating inside the try (so that you need if(allocated) {release}) in the finally clause. This is stupid IMO. Why does everybody advise allocation inside try?
A good question. I was actually surprised by the result myself.
If an InterruptedException occurs the condition will stop awaiting and will then execute the finally. It will obvious not own the lock and propagate an IllegalMonitorStateException.
How about this solution?
public void acquire() throws InterruptedException {
lock.lockInterruptibly();
while (permits == 0) {
condition.await();
}
try {
permits--;
}
finally {
lock.unlock();
}
}
When await returns, the current thread will have the lock. If it gets interrupted while it is waiting to be signaled by other threads (i.e. it does not have the lock), acquire will throw the InterruptedException back up to the caller.
I want to resume the work of interrupted thread,please let me know some possible solutions for the same.
class RunnableDemo implements Runnable
{
public void run()
{
while(thread.isInterrupted())
{
try{}
catch(Exception e){ //exception caught}
}
}
}
If exception is caught, thread is interrupted, but even though exception is caught, i want thread to continue its work, so please suggest me some way to overcome this issue.
Thanks in advance
Thread interruption is something you choose to obey when writing a thread. So if you don't want your thread to be interrupted, don't check the interrupted status and continue regardless.
The only time you'll need try/catch statements (with respect to thread interruption) is when calling blocking methods that throw InterruptedException. Then you'll need to avoid letting that exception stop your thread's work.
Of course... you should give some thought about whether this is a suitable way to behave. Thread interruption is a helpful thing and choosing not to adhere to it can be annoying to users of your code.
I have written a reusable code for getting this feature where thread can be pause and resume. Please find the code below. Your can extend PausableTask and override task() method:
public abstract class PausableTask implements Runnable{
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Future<?> publisher;
protected volatile int counter;
private void someJob() {
System.out.println("Job Done :- " + counter);
}
abstract void task();
#Override
public void run() {
while(!Thread.currentThread().interrupted()){
task();
}
}
public void start(){
publisher = executor.submit(this);
}
public void pause() {
publisher.cancel(true);
}
public void resume() {
start();
}
public void stop() {
executor.shutdownNow();
}
}
Hope this helps. For further details check this link or give me shout in comment section.
http://handling-thread.blogspot.co.uk/2012/05/pause-and-resume-thread.html
A thread get's interrupted only if someone called the interrupt() method of that thread and not because some other random exception was thrown while running your thread as you are thinking.
When the thread's interrupted() method is called, InterruptedException will be thrown in the thread if the thread is in the middle of a blocking operation (eg. IO read).
When the InterruptedException is thrown you should know that the interrupted status is cleared, so the next time you call isInterrupted() in your thread will give you false (even though you just cauth the InterruptedException)
Have this in mind while coding your threads. And if you don't understand what I am talking about stop coding multithreading and go read some books about concurrency in java.
One caveat: If your thread handles an InterruptedException while in a call to a third-party library, then you won't necessarily know how the library reacted to it (i.e., did it leave the library objects in a state when it makes sense for your program to continue using them?)
Some developers (including some library developers) mistakenly assume that an interrupt means, "shut down the program," and all they worry about is closing files, etc.; and not so much about whether the library can continue to be used.
Try it and see, but if you're writing code to control a spacecraft or a nuclear reactor or something, then you may want to do a little extra work to really find out what the library does.
As others already stated, usually interruption is the proper way to cancel a task. If you really need to implement a non-cancellable task, at least make sure to restore the interrupted-state of the thread when you're done with your non-interruptible work:
public void run() {
boolean interrupted = false;
try {
while (true) {
try {
callInterruptibleMethod();
} catch (InterruptedException ex) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted) {
// restore interruption state
Thread.currentThread().interrupt();
}
}
}
(From book: Java Concurrency in Practice)
Suppose I'm executing a synchronized block of code inside some thread and within the synchronized block I call a method that spawns another thread to process a synchronized block of code that requires the same lock as the first method. So in pseudo Java code:
public void someMethod() {
synchronized(lock_obj) {
// a whole bunch of stuff...
// this is the last statement in the block
(new Thread(someOtherMethod())).start();
}
// some more code that doesn't require a lock
}
public void someOtherMethod() {
// some setup code that doesn't require a lock
// return the stuff we want to run in another thread
// that does require a lock
return new Runnable() {
#Override
public void run() {
synchronized(lock_obj) {
// some more code
}
}
};
}
I have no idea how to make sense of that code. Is what I have written even legal? Syntactically I don't see any issues but I'm not sure how to reason through code like that. So when I execute someOtherMethod() in order to create an instance of Runnable in what kind of scope does the code before the return statement run? Does it execute as part of the first synchronized block? Assume there are some other threads working as well that might require the lock on lock_obj.
You are still holding the lock during the creation of runnable and the thread, but after you call start and before the thread actually picks up you are relinquishing the lock. The new thread will have to compete for the lock with other threads.
There's nothing wrong about this code. Before the return statement in someOtherMethod(), the code is running in the synchronized block of someMethod(). After the new thread starts, it will block on the synchronized statement inside the run() method until it obtains a lock on lock_obj (at the earliest, whenever someMethod() exits its synchronized block).
If someMethod() is invoked first, its the classical example of a deadlock.
Is what I have written even legal?
---- Yes it is perfectly legal syntactically.
So when I execute someOtherMethod() in order to create an instance of Runnable in what kind of scope does the code before the return statement run?
----If the someOtherMethod() is invoked from within someMethod() then its in scope of the synchronized block of the someMethod() method.