Controlling an instance's state with AtomicBoolean - java

I need to ensure that a particular start and stop code is executed only once per instance lifecycle, and that the instance cannot be "restarted". Is the following code adequate for a scenario where multiple threads may be acting upon the instance?
public final class MyRunnable {
private final AtomicBoolean active = new AtomicBoolean(false);
private final AtomicBoolean closed = new AtomicBoolean(false);
public void start() {
if (closed.get()) {
throw new IllegalStateException("Already closed!");
}
if (active.get()) {
throw new IllegalStateException("Already running!");
}
active.set(true);
// My one-time start code.
// My runnable code.
}
public void stop() {
if (closed.get()) {
throw new IllegalStateException("Already stopped!");
}
if (!active.get()) {
throw new IllegalStateException("Stopping or already stopped!");
}
active.set(false);
// My one-time stop code.
closed.set(true);
}
}

I would go with a single 3-valued status for two reasons.
Firstly, out of the 4 possible values of the active,closed "tuple" only 3 make sense, setting both to true results in a (possibly benign, but nevertheless) invalid state. You may dismiss it as pure pedantry, but a clear design often brings other benefits.
This leads us neatly to the second, scarier reason:
active.set(false);
// <-- what if someone calls start() here?
closed.set(true); //I assume you wanted to set it to true
As you can see from my comment, you've got a vulnerable spot there, someone could conceivably call start() after you've set active to false but before you set closed to true.
Now you may just say "okay, let's swap the two then and set closed first", but then you have to explain why the two would definitely not be reordered by the JVM. And you'll end up with potentially both flags set to true, resulting in the "invalid state" outlined above.
There is another, separate problem here: the pattern you follow is to call get() to check the value and then set() it to something else later. As PetrosP pointed it out, this isn't an atomic operation, you can call start() a 1000 times with all of them seeing active as false. You need to use compareAndSet instead, which is atomic (this is the whole point of the Atomic* classes), and thus guarantees that only one thread can ever advance the status flag.
So let's combine the two, using a single 3-valued status (I've used AtomicInteger for simplicity, but you can use AtomicReference and a true enum) and compareAndSet():
public final class MyRunnable {
private static final int READY_TO_START = 0;
private static final int ACTIVE = 1;
private static final int STOPPED = 2;
private final AtomicInteger status = new AtomicInteger(READY_TO_START);
public void start() {
if (!status.compareAndSet(READY_TO_START, ACTIVE)) {
throw new IllegalStateException("Already started");
}
// My one-time start code.
}
public void stop() {
if (!status.compareAndSet(ACTIVE, STOPPED)) {
throw new IllegalStateException("Can't stop, either not started or already stopped");
}
// My one-time stop code.
}
}

This solution is not sufficient. Consider tis scenario: Two threads go in start() at the same time. One calls active.get() and it gets false returned. Then the second one calls active.get() and it gets false as well. In this case they will both continue. Then the first one will set active to true. The second one at that point will also set active to true, and they will both continue to the rest of the code that should be run once.
A solution could be this:
public final class MyRunnable {
private final AtomicBoolean active = new AtomicBoolean(false);
private final AtomicBoolean closed = new AtomicBoolean(false);
public void start() {
synchronized (this) {
if (closed.get()) {
throw new IllegalStateException("Already closed!");
}
if (active.get()) {
throw new IllegalStateException("Already running!");
}
active.set(true);
}
// My one-time start code.
// My runnable code.
}
public void stop() {
synchronized (this) {
if (closed.get()) {
throw new IllegalStateException("Already stopped!");
}
if (!active.get()) {
throw new IllegalStateException("Stopping or already stopped!");
}
// My one-time stop code.
closed.set(false);
active.set(false);
}
}
}

Related

How to assert that method is not run concurrently (or fail-fast when it is)?

Is there a way to fail-fast as soon as multiple threads enter a method which is known not to be thread-safe?
Edit: Assuming a method is synchronized externally and not supposed to run concurrently. However, if external synchronization fails for some reason, it would be great to fail as soon as possible, thus avoiding subtle race-condition issues. Also, since the method normally runs in a single thread only, would be great to avoid/minimize synchronization penalty of the check.
The lock solutions, here, all add performance overhead, and I'm guessing you didn't make the class thread-safe for that reason. Java's collections are in the same situation, and they solved it with a "mod count" field in the class. It's not perfect (AtomicInteger would be better), and it's not guaranteed, but it catches most cases.
public class Foo {
private volatile int modCount = 0;
public void threadUnsafeMethod() {
int startModCount = ++modCount;
...
if (modCount != startModCount) { throw new ConcurrentModificationException(); }
}
}
If you just want to guard, you could do
public class Foo {
private final AtomicBoolean inThreadUnsafeMethod = new AtomicBoolean();
public void threadUnsafeMethod() {
if (!inThreadUnsafeMethod.compareAndSet(false, true) {
throw new ConcurrentModificationException();
}
try {
...
} finally {
inThreadUnsafeMethod.set(false);
}
}
}
With both, be very careful with handle reentrant calls correctly. this.otherThreadUnsafeMethod(); shouldn't fail.
Take a look at the ArrayList implementation (search for modCount).
I use an AtomicBoolean. First we have:
private final AtomicBoolean isExecuting = new AtomicBoolean();
Then, first thing we do in method not supposed to be executed concurrently:
if (isExecuting.getAndSet(true)) {
throw new UnsupportedOperationException();
}
Make sure that the one thread executing your method reset the flag on exit:
try {
// ... method implementation
}
finally {
isExecuting.set(false);
}
You may see two real world examples here and here.
You could create a lock and a wrapper method and then you can make each caller to invoke this method
private final Lock lock = new ReentrantLock();
public void wrapperMethod() {
if (!lock.tryLock())
throw new RuntimeException()
try {
threadUnsafeMethod();
}
finally {
lock.unlock();
}
}
With tryLock the caller tries to acquire the lock immediately. If the lock is already been acquired by some other caller it returns false and we throw an exception.
If you want to make each caller to fail fast in case of concurrent invocations, then it means that no two threads access the method concurrently. Otherwise, one of the two threads must have failed. This way you effectively add thread safety to your method.
An equivalent method using atomic longs but that remains a locking mechanism:
AtomicLong threadId = new AtomicLong(-1);
public void wrapperMethod() {
threadId.compareAndSet(-1, Thread.currentThread().getId());
if (threadId.get() != Thread.currentThread().getId())
throw new RuntimeException();
try {
threadUnsafeMethod();
}
finally {
threadId.set(-1);
}
}
Saying that, if you allow to use only a specific thread to run the code, this gives the idea for threads to run a contest. Then use only the winner for running the method:
AtomicLong winningThreadId = new AtomicLong(-1);
public void runContest() {
winningThreadId.compareAndSet(-1, Thread.currentThread().getId());
}
public void wrapperMethod() {
if (winningThreadId.get() != Thread.currentThread().getId())
throw new RuntimeException();
threadUnsafeMethod();
}
So every candidate thread runs the contest once and afterwards it uses the wrapper method.

Safely pausing and resuming a thread

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

Concurrent algorithm for interrupting and restarting a calculation

I am developing an application which performs allows the user to adjust several parameters and then performs a computation which can take up to a minute, after which it displays the result to the user.
I would like the user to be able to adjust the parameters and restart the calculation, terminating the progress of the current calculation.
Additionally, from the programming perspective, I would like to be able to block until the calculation is completed or interrupted, and be able to know which.
In pseudo code, this is roughly what I am looking for:
method performCalculation:
interrupt current calculation if necessary
asynchronously perform calculation with current parameters
method performCalculationBlock:
interrupt current calculation if necessary
perform calculation with current parameters
if calculation completes:
return true
if calculation is interrupted:
return false
What I have so far satisfies the first method, but I am not sure how to modify it to add the blocking functionality:
private Thread computationThread;
private Object computationLock = new Object();
private boolean pendingComputation = false;
...
public MyClass() {
...
computationThread = new Thread() {
public void run() {
while (true) {
synchronized (computationLock) {
try {
computationLock.wait();
pendingComputation = false;
calculate();
} catch (InterruptedException e) {
}
}
}
}
private void checkForPending() throws InterruptedException {
if (pendingComputation)
throw new InterruptedException();
}
private void calculate() {
...
checkForPending();
...
checkForPending();
...
// etc.
}
};
computationThread.start();
}
private void requestComputation() {
pendingComputation = true;
synchronized (computationLock) {
computationLock.notify();
}
}
What is the best way to go about adding this functionality? Or is there a better way to design the program to accomplish all of these things?
If you are using JDK 5 or earlier, check the java.util.concurrent package. The FutureTask class seems to match your requirement: a cancellable asynchronous computation with blocking feature.

Java - Call wait() on an object and then allow object access to method

I have this method which takes a thread as a parameter. I want this method to be able to make a thread wait if there is not one waiting already and then wake up when another thread comes into the method so that the two of them can interact. I think I'm close but after I call wait() on the first thread no other threads can gain access to that method. Here is a minimalist version of my code:
// In the class 'Node'
public synchronized void trade(Thread thread)
{
if (!threadWaiting)
{
threadWaiting = true;
synchronized(thread)
{
try {
thread.wait();
} catch (InterruptedException e) {...}
}
}
}
I apologise for missing anything obvious, I've been looking around for an answer but I'm new to threading so I've no idea what to look for.
So my problem is that when another thread attempts to get into trade() they can't, the debugger just stops right there.
EDIT:
Here's some more clarification on what I'm asking. I'm afraid I wasn't too clear in my original post.
So I have one class called Node and another class called Bot. Bot extends thread so that it can be paused. At the start of the program multiple Bot objects are created and are then started, each Bot will then call the trade() method of the Node and pass itself to the method. If a Bot is the first in the method then I want its thread to wait on the Node until another Bot comes along (The waiting Bot will be stored in the Node), at which point the two Bots will interact.
Below is a clearer example of my method in pseudo code:
// Variable to hold the bot that is waiting.
private Bot waitingBot = null;
// Method belonging to Node.
public synchronized void trade(Bot currentBot)
{
if (waitingBot == null)
{
waitingBot = currentBot;
waitingBot.wait();
}
else
{
currentBot.interactWith(waitingBot);
waitingBot.notify();
waitingBot = null;
}
}
Sorry about the wording of my original post.
Your implementation has a flaw. You are taking lock on parameter passed which will be different for all Threads so they can't interact with wait notify.
EDIT: I am not sure what exactly your aim is but based on details this might help:
EDIT2: Added lock()
private final Lock lck = new ReentrantLock();
private final Condition cnd = lck.newCondition();
private final AtomicBoolean threadwaiting = new AtomicBoolean(false);
public synchronized void trade(Thread thread)
{
lck.lock();
try{
if(threadwaiting.get()){
cnd.signalAll();
threadwaiting.set(false);
//perform your task
}else{
cnd.await();
threadwaiting.set(true);
}
}
} finally {
lck.unlock()
}
}
EDIT:
Looking at your updated post , you should use cyclicbarrier with count 2 then that should solve it all for you.
This is a dead lock, because when you call thread.wait(); you release thread object lock. But this object lock on synchronized method remains, that's why no one else can enter it.
It's like loki's code, but improved
private final Lock lock = new ReentrantLock();
private final Condition cnd = lock.newCondition();
private final AtomicBoolean threadwaiting = new AtomicBoolean(false);
public void trade(Thread thread) {
lock.lock();
if (threadwaiting.get()) {
cnd.signalAll();
lock.unlock();
// perform your task of second thread
} else {
threadwaiting.set(true);
try {
cnd.await();
// perform your task of first thread
} catch (InterruptedException e) {
} finally {
threadwaiting.set(false);
lock.unlock();
}
}
}

java: executors + tasks + locks

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.

Categories