I'm synchronizing on the object of the thread like this:
synchronized(threadObject){
try{
threadObject.interrupt();
}catch(Exception ex){
//catch error here.
}finally{
threadObject.notifyAll();
}
}
Now, my questions are:
It is possible to interrupt a thread
inside a synchronized block whose
object that was synchronized was the
thread to be interrupted? Like in
the sample code.
Can I still notify other threads
holding the interrupted thread's
object? Like in the sample code.
It is possible to interrupt a thread inside a synchronized block whose object that was synchronized was the thread to be interrupted? Like in the sample code.
Yes. I can't see why that wouldn't work. The synchronized keyword is quite orthogonal to the interrupt method. (Note that contrary to await and notify, you're not required to own the objects monitor when calling interrupt.)
Can I still notify other threads holding the interrupted thread's object? Like in the sample code.
Yes, you can call notifyAll on any object as long as you own the objects monitor. Again, the wait/notify-mechanism is quite orthogonal to the interrupt method.
Your question seem to indicate that you've misunderstood the use of synchronized. The usual use-case is to synchronize on an object representing some resource which you like to avoid concurrent access to. The thread itself rarely represent such resource.
The object works as it normally does. The only stipulation is that other threads that synchronize on threadObject's monitor will block until you're complete with your thread. So yes, you can do both of those.
Yes: But you don't really need to have the lock before calling interrupt.
Yes
The answer to both questions is yes.
However, there is something a bit strange about your example. I've never come across a case where you would use a Thread as a primitive lock. And it what you are doing in the example doesn't seem to achieve anything.
If threadObject is the same as Thread.currentThread(), then the call to interrupt() will just set this thread's interrupted flag ... which be noticed in that code fragment.
if threadObject is some other Thread object then that thread will be interrupted. But we can't see (here) the code that that thread will be executing, and we don't know if it will be waiting on threadObject. If not the interrupt() and notify() well got to different threads ...
The bottom line is that you wouldn't normally use a Thread object as a lock, and you wouldn't normally send use an interrupt() as an ersatz notify().
(Maybe this example is not intended to represent a real use-case.)
Related
May I include a synchronized block inside another one for synchronizing another object?
Example:
synchronized(myObjetc1){
// code
synchronized(myObjetc2){
// code
}
}
If so, still, is it a correct technique or is it too risky?
It will be fine if you synchronize in the same order everywhere else.
If some other thread were to execute the following code
synchronized(myObjetc2){
// code
synchronized(myObjetc1){
// code
}
}
you might get a deadlock.
Assuming the variables above are referencing the same objects, consider the following case. The first thread (your code) locks the monitor on myObjetc1. The thread scheduler switches thread context. The second thread (the above code) locks the monitor on myObjetc2. The thread scheduler switches thread context. The first thread attempts to lock the monitor on myObjetc2. It has to wait because the second thread has it. The thread scheduler switches context. The second thread attempts to lock the monitor on myObjetc1. It has to wait because the first thread has it. Boom! Deadlock.
Yes, you can do it.
Till the time you are following lock rules and doing so solves your requirement, its Fine.
However, many times something like this invites DeadLock problem, if done incorrectly.
I'm just trying to further my understanding of this concept.
We have a monitor, let's say a queue or a map of some sort. This monitor has methods to put objects on, and get objects off. In order to be thread safe, the monitor will lock on it's put methods and on it's get methods. When a thread is synchronized to this monitor, it's constantly trying to obtain this monitor's right's so it can proceed with what it needs to do. Does this sound right?
Another question, how does the flow of control work here. Which code is executed once the thread has gained access to the monitor? I'm finding it hard to debug multi-threaded programs with just print statements, it get's really messy and confusing.
public void run(){
try{
synchronized (monitor){
while (monitor is empty){
monitor.wait(); // Does this line pause the thread or the monitor?
}
System.out.println("Done Waiting");
}
System.out.println("Out of the synchronized block");
}
}
Here's the definition from the Java Language Specification:
The Java programming language provides multiple mechanisms for
communicating between threads. The most basic of these methods is
synchronization, which is implemented using monitors. Each object in
Java is associated with a monitor, which a thread can lock or unlock.
Only one thread at a time may hold a lock on a monitor. Any other
threads attempting to lock that monitor are blocked until they can
obtain a lock on that monitor. A thread t may lock a particular
monitor multiple times; each unlock reverses the effect of one lock
operation.
To answer
This monitor has methods to put objects on, and get objects off. In
order to be thread safe, the monitor will lock on it's put methods and
on it's get methods. When a thread is synchronized to this monitor,
it's constantly trying to obtain this monitor's right's so it can
proceed with what it needs to do. Does this sound right?
So you're not interacting with a monitor. A monitor doesn't have a concept of methods. Don't think of it like that. You interact with objects which have monitors. When a thread acquires an object's monitor, it doesn't need to constantly trying to obtain it, it already has it.
Another question, how does the flow of control work here. Which code
is executed once the thread has gained access to the monitor? I'm
finding it hard to debug multi-threaded programs with just print
statements, it get's really messy and confusing.
If execution enters the synchronized block on an object, the currently executing thread has acquired the monitor on the synchronized object, in this case the object referenced by the variable monitor.
I'll assume (thanks to Radiodeaf) that by monitor is empty, you mean your Map object doesn't have any entries.
When you call
monitor.wait();
the current thread releases the monitor on the object referenced by monitor and sleeps until it gets notified.
The javadoc of Object#wait() has more details.
So you will loop on the check for empty and wait if it returns true. We can assume that some other piece of code calls notify() when they put something into the Map.
When the object does get notified, the thread then has to compete to re-acquire the object's monitor. This is obviously necessary so that the thread can be executing inside a synchronized block on the object.
As we know We can call wait method only from synchronized context.
So By saying wait release the lock we mean that once lock is acquired on an object when it is in synchronized context , by calling wait method on same object , it release the lock and allow other thread to work on that object.
What is the cost associated with calling notify() on an Object on which no other Objects have called wait() in Java?
The reason I am interested in this is because I have a worker thread that has a queue of Objects.
The thread loops continuously checking if it has any Objects in the queue that it needs to work with. If it loops and there is nothing in said queue the thread calls wait on on a separate Object.
When another thread adds an Object to the queue it calls notify on the Object that the worker thread would be waiting on regardless if the working thread is actually waiting.
Before anyone says anything, it is all synchronized correctly and won't throw any exceptions/errors.
My question is: is this setup slower then just having the worker thread just continue checking and never call wait() and what is the cost of calling notify() without any threads waiting on the Object?
Thanks for the help in advance :)
If you don't block worker thread, it'll be a busy-wait "spinloop" pattern, e.g. something like:
while (queue.isEmpty()) {
Thread.yield();
}
I've been reading about this model of conditional waiting today (in regards of my own problem :)) and found the following notes about when such model might show superior performance to ordinary wait() - notify() scheme:
... The main exceptions are those cases in which you somehow know that the condition must become true within some very short, boudned amount of time. In such cases, the time wasted spinning might be less than the time required to suspend and resume threads.
The book is "Concurrent Programming in Java: Design Principles and Patterns" by Doug Lea.
I have a thread:
class Foo extends Thread
{
boolean active = true;
public void run()
{
while(active)
{
//do stuff
}
}
public void end()
{
active = false;
}
public void hibernate()
{
synchronized(this)
{
wait();
}
}
}
If another thread calls end(), will Foo immediately see that active is now false? Specifically, because active isn't volatile, I'm not sure that it will. I initially created end() as a clever way of avoiding volatile, but now I'm unsure that it will actually do what I intend.
Additionally, if another thread calls hibernate(), which thread will go to sleep? I'm intending Foo to sleep, so if this doesn't do what I intend, an alternative suggestion would be very welcome.
If another thread calls end(), will Foo immediately see that active is now false?
No it won't. Or at least, it won't see it all of the time.
If you want run to always see the new value immediately, there has to be a "comes after" relationship between the thread assigning to the variable and the thread reading it. This can be achieved:
by declaring active volatile,
by putting synchronized blocks around the statements that read and write the variable,
by making the variable an "atomic" type; e.g. AtomicBoolean, or
by using some other appropriate concurrency class; see the java.util.concurrent.* packages.
... a clever way of avoiding volatile ...
Declaring the variable to be volatile is one way of ensuring proper synchronization. It is a fact that proper synchronization imposes a performance overhead. However, proper synchronization is essential for your application to work reliably, and it is NOT "clever" to avoid it.
(Without proper synchronization, your program will probably still work most of the time, and it might even always work on some machines. However, occasionally it won't work, and the actual behavior is likely to depend on what machine you run the program on, what the machine load is, and other things.)
Additionally, if another thread calls hibernate(), which thread will go to sleep?
The thread that makes the call will go to sleep. And it won't wake up unless some other thread does a notify or notifyAll on the same Foo object.
If you simply want the application to go to sleep and wake up a bit later, use Thread.sleep. But beware that using sleep in the wrong way can make your application slow and unresponsive.
Your suspicion is correct: because active isn't volatile, there is no guarantee that run() will ever see the change made on another thread.
Generally speaking, “clever” ways of avoiding volatile are almost always a bad idea. In fact, even volatile is something you should prefer not to resort to. Most of the time it's safer to stick to locks, monitors, or higher-level synchronization mechanisms.
For your second question, the thread that will go to sleep is the one that called hibernate(). That thread will sleep until it is interrupted, it experiences a spurious wakeup, or some other thread calls notify()/notifyAll() on the Foo instance's monitor. It is usually a mistake to call Object#wait() without surrounding it with a loop that checks the condition being waited for.
You also seem to be confused about the idea of a Foo instance “going to sleep”. A Foo instance isn't a Thread (or even a Runnable), and doesn't create its own thread, so the idea of it going to sleep doesn't make a lot of sense. What you are probably trying to achieve is putting the thread calling Foo#run() to sleep.
Regarding your first question of avoiding volatile , you should try using Thread interruption to signal a running thread to stop.
Use interrupt() instance method from another thread to interrupt running thread.
Use isInterrupted() method in your running thread to check for interruption.
while(!this.isInterrupted()){
//do your work here.
}
Not sure why you want to extend Thread class. If you implements Runnable in that case you should use interrupted in your run method to check for interruption . Please read javadocs to know about some caveats of this method.
Someone at work just asked for the reasoning behind having to wrap a wait inside a synchronized.
Honestly I can't see the reasoning. I understand what the javadocs say--that the thread needs to be the owner of the object's monitor, but why? What problems does it prevent? (And if it's actually necessary, why can't the wait method get the monitor itself?)
I'm looking for a fairly in-depth why or maybe a reference to an article. I couldn't find one in a quick google.
Oh, also, how does thread.sleep compare?
edit: Great set of answers--I really wish I could select more than one because they all helped me understand what was going on.
Lots of good answers here already. But just want to mention here that the other MUST DO when using wait() is to do it in a loop dependent on the condition you are waiting for in case you are seeing spurious wakeups, which in my experience do happen.
To wait for some other thread to change a condition to true and notify:
synchronized(o) {
while(! checkCondition()) {
o.wait();
}
}
Of course, these days, I'd recommend just using the new Condition object as it is clearer and has more features (like allowing multiple conditions per lock, being able to check wait queue length, more flexible schedule/interrupt, etc).
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
while (! checkCondition()) {
condition.await();
}
} finally {
lock.unlock();
}
}
If the object does not own the object monitor when it calls Object.wait(), it will not be able to access the object to setup a notify listener until the the monitor is released. Instead, it will be treated as a thread attempting to access a method on a synchronized object.
Or to put it another way, there is no difference between:
public void doStuffOnThisObject()
and the following method:
public void wait()
Both methods will be blocked until the object monitor is released. This is a feature in Java to prevent the state of an object from being updated by more than one thread. It simply has unintended consequences on the wait() method.
Presumably, the wait() method is not synchronized because that could create situations where the Thread has multiple locks on the object. (See Java Language Specifications/Locking for more info on this.) Multiple locks are a problem because the wait() method will only undo one lock. If the method were synchronized, it would guarantee that only the method's lock would be undone while still leaving a potential outer lock undone. This would create a deadlock condition in the code.
To answer your question on Thread.sleep(), Thread.sleep() does not guarantee that whatever condition you are waiting on has been met. Using Object.wait() and Object.notify() allows a programmer to manually implement blocking. The threads will unblock once a notify is sent that a condition has been met. e.g. A read from disk has finished and data can be processed by the thread. Thread.sleep() would require the programmer to poll if the condition has been met, then fall back to sleep if it has not.
It needs to own the monitor, since the purpose of the wait() is to release the monitor and let other threads obtain the monitor to do processing of their own. The purpose of these methods (wait/notify) is to coordinate access to synchronized code blocks between two threads that require each other to perform some functionality. It is not simply a matter of making sure access to a data structure is threadsafe, but to coordinate events between multiple threads.
A classic example would be a producer/consumer case where one thread pushes data to a queue, and another thread consumes the data. The consuming thread would always require the monitor to access the queue, but would release the monitor once the queue is empty. The producer thread would then only get access to write to the thread when the consumer is no longer processing. It would notify the consumer thread once it has pushed more data into the queue, so it can regain the monitor and access the queue again.
Wait gives up the monitor, so you must have it to give it up. Notify must have the monitor as well.
The main reason why you want to do this is to ensure that you have the monitor when you come back from wait() -- typically, you are using the wait/notify protocol to protect some shared resource and you want it to be safe to touch it when wait returns. The same with notify -- usually you are changing something and then calling notify() -- you want to have the monitor, make changes, and call notify().
If you made a function like this:
public void synchWait() {
syncronized { wait(); }
}
You would not have the monitor when wait returned -- you could get it, but you might not get it next.
Here's my understanding on why the restriction is actually a requirement. I'm basing this on a C++ monitor implementation I made a while back by combining a mutex and a condition variable.
In a mutex+condition_variable=monitor system, the wait call sets the condition variable into a wait state and releases the mutex. The condition variable is shared state, so it needs to be locked to avoid race conditions between threads that want to wait and threads that want to notify. Instead of introducing yet another mutex to lock its state, the existing mutex is used. In Java, the mutex is correctly locked when the about-to-wait thread owns the monitor.
Mostly wait is done if there is a condition say a queue is empty.
If(queue is empty)
queue.wait();
Let us assume the queue is empty.
In case if the current thread pre-empts after checking the queue, then if another
thread adds few elements to queue, the current thread will not know and will go for wait
state. Thats wrong.
So we should have something like
Synchornized(queue)
{
if(queue is empty)
queue.wait();
}
Now let us consider what if they made wait itself as synchronized. As already mentioned in one of the comments, it releases only one lock. That means if wait() was synchronized in the above code only one lock would have been released. Implies that current thread will go for wait with the lock for the queue.