I have a long-running Runnable. It performs a large number of iterations inside a while-loop in its run() function. I need functionality to pause and resume the runnable, which I implemented using a volatile Boolean pauseFlag that can be set by another thread.
Once the Runnable has detected that pauseFlag is true, it calls pauseFlag.wait() to pause its execution. Resuming is done through setting pauseFlag to false and then calling pauseFlag.notifyAll().
So the pauseFlag both acts as a flag and a mutex. This combined functionality does not work, however. The Runnable keeps blocking on pauseFlag.wait() indefinitely.
If I create a separate mutex, say, Object mutex = new Object(); and use mutex.notifyAll() / mutex.wait(), while still using pauseFlag as a boolean flag, the Runnable does behave as intended.
The non-working code is shown below:
public class PausableRunnable implements Runnable
{
private boolean done;
private volatile Boolean pauseFlag = false;
/** Pause execution. This is an asynchronous (non-blocking) call. */
public void pause() // <-- called by another thread
{
pauseFlag = true;
}
/** Resume execution */
public void resume() // <-- called by another thread
{
pauseFlag = false;
synchronized (pauseFlag)
{
pauseFlag.notifyAll();
}
}
#Override
public void run()
{
try
{
while (!done && !Thread.currentThread().isInterrupted())
{
while (pauseFlag)
{
synchronized (pauseFlag)
{
// Pause flag was set. Suspend until we are notified that we can continue
pauseFlag.wait();
}
}
// execute our main behaviour. set done = true when done iterating.
// ....
}
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
So, while I have found a solution by using a separate object, I'd like to understand the issue. Why doesn't the above implementation work?
I made this very same mistake once.
wait/notify works on an object, not a reference
When you change the object referred to by
private volatile Boolean pauseFlag
the wait is still referring to the original object. (As pointed out in the comments, there will usually be only two Boolean objects, TRUE and FALSE, making this even harder to debug, because you might get the correct one by chance)
So it's best to use a final reference that never changes its underlying object when using wait/notify.
Related
I'm studying for an exam from a Book given by my professor and there is this code working with Threads and Synchronization: We want to be notified everytime the state changes (without missing a state change).
public class C {
private int state = 0; // the state
private boolean modified = false; // to show if the state was changed since actualization
public synchronized void printNewState() {
while (true) {
if (!modified) {
wait();
}
System.out.println(state);
modified = false;
notify();
}
}
public synchronized void setValue(int v) {
if (modified) {
wait();
}
state = v;
notify();
modified = true;
System.out.println("value set");
}
}
And then it's writen:
However, it is not guaranteed that notify() in the method SetValue(int) wakes up the printNewState Thread! In Java we solve this problem
with the help of notifyAll() and take a little busy waiting:
public synchronized void printNewState() {
while (true) {
while (!modified) {
wait();
}
System.out.println(state);
modified = false;
**notify();** \\(?)
}
}
public synchronized void setValue(int v) {
while (modified) {
wait();
}
state = v;
notifyAll();
modified = true;
System.out.println("value set");
}
I don't understand why the notify wasn't also changed to notifyAll()? It might not be guaranteed that this notify goes to a Thread of setValue(int) ???
Thank you
The notify() method wakes up a single waiting thread, whereas the notifyAll() method wakes up all the waiting threads. The problem is that with notify(), the thread that is woken up is effectively random.
If some other thread is accidentally or maliciously wait()ing on the same object, it could receive the notification instead of the thread you expect to wake up.
Take a look at this answer for some more information. The comments on that answer are also quite interesting.
EDIT
In the code sample you posted, the first notify() within printNewState() can handle only one update at a time, so it doesn't make sense to notify all waiting threads to post their updates. The code assumes, however, that only threads invoking setValue(int) are waiting.
Since public synchronized void setValue(int) is essentially the same as having synchronized(this) as the first line of the method, that isn't actually guaranteed. Any code that has a reference to an instance of C class can wait on it and screw up the code.
The synchronization and wait/notify actions should happen on an object lock/monitor. private final Object monitor = new Object(), synchronized(this.monitor), this.monitor.wait(), this.monitor.notifyAll(), etc.
I would also like to note that modified = true needs to be placed before notifyAll() in setValue(int), otherwise other waiting update threads will proceed without printNewState() noticing the update.
Also, private boolean modified should really be private volatile boolean modified, and the same for private int state, though an AtomicInteger may be a better option.
I am creating a mutli threaded application, and I have a question regarding the use of synchronized methods.
Lets say I have the following component which would be accessed by multiple threads.
Component.java
public class Component {
private boolean active;
//Constructor
public Component(){
active = false;
}
synchronized public void initiate(){
//do something
active = true;
}
synchronized public void closedown(){
//do something
active = false;
}
public void doSomething(){
//do something
}
public boolean isActive(){
return active;
}
}
If I have two threads accessing the the same Component object and the first thread gets halted in the Component.closedown() before it has set active = false, and the second thread picks up and calls Component.isActive(), will the second thread block until the first thread has finished the closedown, or will it get the returned value of true?
If it is the latter, how can I make this thread safe?
Yes, that is the essence of mutual-exclusion locks (mutexes). If a thread gets descheduled by the OS while holding a mutex, all other threads requiring the mutex to proceed will be stalled.
The above is actually the reason why, even if we take care to make all our critical sections very short and fast to execute, mutexes will still cause occasional latency spikes, and the spikes will be huge in proportion to regular latency. For example, your simple getter will execute in a couple of nanoseconds when uncontended, but may take 10µs or more if the thread holding the mutex is descheduled at an inconvenient time.
NOTE: The code in your question lacks the synchronized designation on isActive, but I assume your question is about what would happen if it was synchronized—because the code has a data race without it. Specifically:
will the second thread block until the first thread has finished the closedown, or will it get the returned value of true?
Without synchronized it will do neither: it won't block, but it won't be guaranteed to ever return the true value. You are only guaranteed to observe the initial value (that's what the data race is about).
If you are looking for a practical advice to improve your code, then don't synchronize isActive method, but make the active flag volatile. This is standard practice for your use case.
You need to have use a lock to protect the critical sections. As some methods read from the value and some write to the value, you can try using a ReadWriteLock.
public class Component {
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private boolean active;
//Constructor
public Component(){
active = false;
}
public void initiate(){
// non-critical section
rwl.writeLock().lock();
try {
// critical section
active = true;
} finally {
rwl.writeLock().unlock();
}
}
public void closedown(){
// non-critical section
rwl.writeLock().lock();
try {
// critical section
active = false;
} finally {
rwl.writeLock().unlock();
}
}
public void doSomething(){
// do something
}
public boolean isActive(){
rwl.readLock().lock();
boolean status = active;
rwl.readLock().unlock();
return status;
}
}
The following code will work, but I slightly resent having to write the isRunning() method:
class Test {
private boolean running;
public void startX() {
synchronized(this) {
running = true
}
while (isRunning()) {
//do something
}
}
public synchronized void stopX() {
running = false;
}
private synchronized boolean isRunning() {
return running;
}
}
Can I synchronize reads of the running variable in the while (running){} in some other way, or do I have to write the isRunning() method? The same question applies to other control variables as well, eg
for (;running;) {}
or
if (running) {}
In all of these cases it seems as though you're forced into writing a pointless method to get the synchronization correct. Am I missing something?
if you are only resetting the value of running once to designate to stop, you might be able to use the volatile keyword.
However, if you need to start and stop many times, this won't work. This is because volatile fields "may miss an update"
Here's a link to explanation of when volatile works in cases like this link
here's the code sample from that link incase it goes dead:
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
while (!pleaseStop) {
// do some stuff...
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
If you need to start and stop many times, then you need to either use one of the Java 5 concurrent lock objects or explicit synchronization
You could make the running field volatile. Making the field volatile puts the JVM on notice that it should make changes to that field visible to other threads.
The "miss an update" caveat is for cases where you want to read a value and update based on that value, which doesn't seem applicable here.
Multiple threads can write to this field, if all they're doing is setting a boolean flag then this won't be a problem.
Alternatively, if you are trying to cancel a thread, there's already an equivalent flag provided on Thread for this (and the visibility issue is taken care of). You can call interrupt on a thread, the code in the Runnable can query Thread.currentThread().isInterrupted() in order to tell whether it's been interrupted. This is preferable over using your own flag because the interruption will cause the thread to wake up if it is waiting or sleeping. With your own flag you have to wait until control reaches a place where the flag can be tested.
just to add up to other people's answer that suggested volatile .
Alternatively you could create a class for the checks.
I have made the variable to be static, so all threads will be pointing to same object.
class Runner{
boolean static running=true;
public static synchronized boolean getRunning(){
return running;
}
public static synchronized boolean setRunning(boolean r){
running=r;
}
}
NOTE:
if you don't require the global variable, then remove the static
I want to create a thread to make some HTTP requests every few seconds and is easy to pause and resume at a moments notice.
Is the way below preferred, safe and efficient?
public class Facebook extends Thread {
public boolean running = false;
public void startThread() {
running = true;
}
public void stopThread() {
running = false;
}
public void run() {
while(true) {
while(running) {
//HTTP Calls
Facebook.sleep(2000);
}
}
}
}
Your Code:
In your example, the boolean should be volatile boolean to operate properly. The other issue is if running == false your thread just burns CPU in a tight loop, and you probably would want to use object monitors or a Condition to actually wait idly for the flag to become true again.
Timer Option:
I would suggest simply creating a Timer for this. Each Timer implicitly gets its own thread, which is what you are trying to accomplish.
Then create a TimerTask (FacebookTask below is this) that performs your task and from your main control class, no explicit threads necessary, something like:
Timer t;
void resumeRequests () {
if (t == null) { // otherwise its already running
t = new Timer();
t.scheduleAtFixedRate(new FacebookTask(), 0, 2000);
}
}
void pauseRequests () {
if (t != null) { // otherwise its not running
t.cancel();
t = null;
}
}
Note that above, resumeRequests() will cause a request to happen immediately upon resume (as specified by the 0 delay parameter); you could theoretically increase the request rate if you paused and resumed repeatedly in less than 2000ms. This doesn't seem like it will be an issue to you; but an alternative implementation is to keep the timer running constantly, and have a volatile bool flag in the FacebookTask that you can set to enable/disable it (so if it's e.g. false it doesn't make the request, but continues checking every 2000ms). Pick whichever makes the most sense for you.
Other Options:
You could also use a scheduled executor service as fge mentions in comments. It has more features than a timer and is equally easy to use; they'll also scale well if you need to add more tasks in the future.
In any case there's no real reason to bother with Threads directly here; there are plenty of great tools in the JDK for this job.
The suggestion to using a Timer would work better. If you want to do the threading manually, though, then something more like this would be safer and better:
class Facebook implements Runnable {
private final Object monitor = new Object();
public boolean running = false;
public void startThread() {
synchronized (monitor) {
running = true;
monitor.notifyAll();
}
}
public void stopThread() {
synchronized (monitor) {
running = false;
}
}
#Override
public void run() {
while(true) {
try {
synchronized (monitor) {
// Wait until somebody calls startThread()
while (!running) {
monitor.wait();
}
}
//HTTP Calls
Thread.sleep(2000);
} catch (InterruptedException ie) {
break;
}
}
}
}
Note in particular:
You should generally implement Runnable instead of subclassing Thread, then use that Runnable to specify the work for a generic Thread. The work a thread performs is not the same thing as the thread itself, so this yields a better model. It's also more flexible if you want to be able to perform the same work by other means (e.g. a Timer).
You need to use some form of synchronization whenever you want two threads to exchange data (such as the state of the running instance variable). There are classes, AtomicBoolean for example, that have such synchronization built in, but sometimes there are advantages to synchronizing manually.
In the particular case that you want one thread to stop work until another thread instructs it to continue, you generally want to use Object.wait() and a corresponding Object.notify() or Object.notifyAll(), as demonstrated above. The waiting thread consumes zero CPU until it is signaled. Since you need to use manual synchronization with wait/notify anyway, there would be no additional advantage to be gained by using an AtomicBoolean.
Edited to add:
Since apparently there is some confusion about how to use this (or the original version, I guess), here's an example:
class MyClass {
static void main(String[] args) {
FaceBook fb = new FaceBook();
Thread fbThread = new Thread(fb);
fbThread.start();
/* ... do stuff ... */
// Pause the FaceBook thread:
fb.stopThread();
/* ... do more stuff ... */
// Resume the FaceBook thread:
fb.startThread();
// etc.
// When done:
fbThread.interrupt(); // else the program never exits
}
}
I Would recommend you to use a guarded blocks and attach the thread to a timer
Suppose I have an ExecutorService (which can be a thread pool, so there's concurrency involved) which executes a task at various times, either periodically or in response to some other condition. The task to be executed is the following:
if this task is already in progress, do nothing (and let the previously-running task finish).
if this task is not already in progress, run Algorithm X, which can take a long time.
I'm trying to think of a way to implement this. It should be something like:
Runnable task = new Runnable() {
final SomeObj inProgress = new SomeObj();
#Override public void run() {
if (inProgress.acquire())
{
try
{
algorithmX();
}
finally
{
inProgress.release();
}
}
}
}
// re-use this task object whenever scheduling the task with the executor
where SomeObj is either a ReentrantLock (acquire = tryLock() and release = unlock()) or an AtomicBoolean or something, but I'm not sure which. Do I need a ReentrantLock here? (Maybe I want a non-reentrant lock in case algorithmX() causes this task to be run recursively!) Or would an AtomicBoolean be enough?
edit: for a non-reentrant lock, is this appropriate?
Runnable task = new Runnable() {
boolean inProgress = false;
final private Object lock = new Object();
/** try to acquire lock: set inProgress to true,
* return whether it was previously false
*/
private boolean acquire() {
synchronized(this.lock)
{
boolean result = !this.inProgress;
this.inProgress = true;
return result;
}
}
/** release lock */
private void release() {
synchronized(this.lock)
{
this.inProgress = false;
}
}
#Override public void run() {
if (acquire())
{
// nobody else is running! let's do algorithmX()
try
{
algorithmX();
}
finally
{
release();
}
}
/* otherwise, we are already in the process of
* running algorithmX(), in this thread or in another,
* so don't do anything, just return control to the caller.
*/
}
}
The lock implementation you suggest is weak in the sense that it would be quite easy for someone to use it improperly.
Below is a much more efficient implementation with the same improper use weaknesses as your implementation:
AtomicBoolean inProgress = new AtomicBoolean(false)
/* Returns true if we acquired the lock */
private boolean acquire() {
return inProgress.compareAndSet(false, true);
}
/** Always release lock without determining if we in fact hold it */
private void release() {
inProgress.set(false);
}
Your first bit of code looks pretty good, but if you're worried about algorithmX recursively invoking the task, I would suggest you use a java.util.concurrent.Semaphore as the synchronization object, rather than a ReentrantLock. For example:
Runnable task = new Runnable() {
final Semaphore lock = new Semaphore( 1 );
#Override public void run() {
if (lock.tryAcquire())
{
try
{
algorithmX();
}
finally
{
lock.release();
}
}
}
}
Note in particular the use of tryacquire. If acquiring the lock fails, algorithmX is not run.
ReentrantLock seems fine to me. The only situation where I'd find interesting to manually create a lock using AtomicInteger will be if you have a really short algorithmX which is not your case.
I think the secret of choosing the right lock impl is this:
* if this task is already in progress, do nothing (and let the previously-running task finish).
What does "do nothing" mean in this context? Thread should block and retry execution after running algorithmX is finished?. If this is the case semaphore.acquire instead of tryAcquire should be used and AtomicBoolean solution won't work as expected.