I need to do an update operation asynchronously when I receive a notification. The update() method below manipulates instance variables.
public class UpdateOperation implements Runnable
{
private Boolean isInProgress = false;
@Override
public void run() {
try
{
synchronized (isInProgress)
{
isInProgress = true;
}
update(); //perform update
synchronized (isInProgress)
{
isInProgress = false;
}
}
catch (UpdaterException e)
{
// deal with it
}
}
}
// In another class
private UpdateOperation mCurrentUpdateOperation = new UpdateOperation();
public void updateRequired()
{
synchronized (mCurrentUpdateOperation.isInProgress)
{
if (!mCurrentUpdateOperation.isInProgress)
{
new Thread(mCurrentUpdateOperation).start();
}
else
{
// reschedule or silently ignore
}
}
}
Is this setup sufficient for no two (2) update operations to run concurrently? I believe it is because the first thread to reach the synchronized block will acquire the lock, launch the operation, and release the lock. Then the second (or more) will acquire the lock, see that operation is in progress, reschedule, and release the lock.
Can this setup ever fail?
No because of the object you are locking on. You should always synchronize on a non-final object and never on a
Boolean. As the value ofisInProgresschanges (as it is set totrueorfalse), multiple threads will be locking different objects and can enter the mutex block at the same time.You could instead lock on your
UpdateOperationinstance if it could be madefinal. You can always do something like:Once you lock the object you can check the state of the
inProgresswhich could be a boolean primitive. Thesynchronizeconstruct syncs all memory. See the Java thread tutorial on synchronization for more information.Locking on a
Booleanis specifically bad because there are only 2 constant object references for them in the entire JVM (unless you donew Boolean(...)). When you say:you are in effect saying:
So all threads in all classes will be locking on the same 2 objects with bizarre results.
For more information see my answer here: