So what's the best way to pause a thread? So far I have something like this: In main loop of the thread, first line is:
while (paused == true) {
Thread.sleep(refreshRate);
}
And it works perfercly. I can change paused state pressing P key. But Im looking for better, more professional solution. I know about reentrant locks and conditions. So I could use them on the thread. And then presing P would release singalAll() method. But it would slow my app a lot because of synchronization which I don't really need in this thread. So what is the best, most perform way to solve it? Maybe using synchronization blocks?
synchronized (new Object()) {
}
Then just part of code would be synchronized. Or maybe I should use semaphores?
You should use a wait/notify scheme such as:
Create an atomic boolean flag in the thread to be paused.
When the flag is set the thread should call wait() on a lock object
When you want to unpause the thread reset the flag and call notify() on the lock object
Use a PauseableThread like the one I posted a while ago in answer to a question much like yours.
It uses ReadWriteLocks to implement so you don't have the overhead of synchronization.
Use wait() and notify()
Object waitLock = new Object();
//...
// waiter Thread
synchronized (waitLock) {
waitLock.wait();
}
// wake up with
waitLock.notify();
Related
I have a relatively simple issue to solve, namely I would like to make all threads await a certain condition to happen and then proceed. It can be explained by the code below:
void doSth(){ //shared by multiple threads
...
if(!conditionMet())
await();
//procceed further
resetCondition()
}
I do not want to use locking and conditions, as it seems unnecessary. CountDownLatch would be perfect, but I have to reset the latch, and CyclicBarrier would not work either because I have no idea how many threads need to call await. Also, when the signal is sent to awaiting threads, they should all be released and proceed. How would you guys approach this?
I recommend Phaser
I have no idea how many threads need to call await.
For each thread that eventually needs to wait, invoke phaser.register() [register doesn't wait, it tells the phaser to expect another thread to either wait or to trip the barrier]
CountDownLatch would be perfect, but I have to reset the latch
Once a thread completes, invoke phaser.arriveAndAwaitAdvance(). At that point, all threads will wait there until the number of threads registered == number of threads arrived.
I do not want to use locking and conditions, as it seems unnecessary.
Why? This smacks of premature optimization to me. If you don't know how many threads there are then you can't use CountDownLatch. This seems to me to be a perfect use case of standard locks and conditions. The only time we worry about their use is when we are trying hard not to get threads to block. But in this case blocking is exactly what you want.
I don't really see why you wouldn't want to use locks? Any "barrier" mechanism will internally use some form of synchronization, so there's no real "unleash all threads at the same time" solution.
Best I can come up with:
private final Object lock = new Object();
void doSth() { //shared by multiple threads
...
synchronized(lock) {
while(!conditionMet()) {
lock.wait();
}
}
}
void release() {
synchronized(lock) {
resetCondition();
lock.notifyAll();
}
}
I wanted to know if it's possible to use wait() on a synchronized piece of code without using notify(), something like this:
wait_on(B):
synchronized(B.monitor) {
B.count--
while (B.count > 0) { /* wait */ }
}
Thanks in advance
You need notify or notifyAll to awaken the thread from its wait state. In your sample the code would enter the wait and stay there (unless interrupted).
Know the difference between wait, yield, and sleep. Wait needs to be called in a synchronized block, once the wait is entered the lock is released, and the thread stays in that state until notify is called. Yield returns the thread to the ready pool and lets the scheduler decide when to run it again. Sleep means the thread goes dormant for a fixed period of time (and from there it goes to the ready pool).
Make sure you call wait on the same object that you’re synchronizing on (here it’s B.monitor).
No! Only option is to wait with a timeout, which surely will not help you.
If you change the /* wait */ into a call to wait(), and no one will call notify() or notifyAll(), then this thread will never wake up...
If it is a barrier that you want, you will need to notifyAll your other threads:
wait_on(B) {
synchronized(B.monitor) {
B.count--
while (B.count > 0) {
B.monitor.wait()
}
B.monitor.notifyAll();
}
}
Regards,
Pierre-Luc
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.
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.)
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.