Question

I get mixed answer whenever I look for concurrent access , JCIP book I have already ordered and is on the way , but I want to nail this concurrency basics of mine , here is my scenario

I have 3 threads. One thread is responsible for establishing a connection and creates a singleton connection object instance.The other two threads will be sending data incessantly.

Now the other threads will wait on a CountDownLatch which will be counted down to zero by the connection thread once the connection has been established.

Here is what I have declared in the ConnectStatus class in hope of connected variable being synchronized and visible to all the threads.

public class ConnectStatus {

public static final CountDownLatch connectionLatch = new CountDownLatch(1);
private static volatile AtomicBoolean connected;

}

I am using this connected variable which is volatile & atomic to maintain the connection status. So that the other threads can know "always" whether the connection is alive before sending data.

Once I establish the connection , I am making this boolean as true and latch as zero.

ConnectStatus.connected.set(true);
ConnectStatus.connectionLatch.countdown();

Now the other threads will get notified by the latch and also the atomic value will be true and threads start sending out the data.

Send data thread snippet below.

if(ConnectStatus.connected.get()){

   // send data

}

Now here is my problem , The connection can get bad and disconnected at anytime,so that time , I am making my atomic connected as false. What I would like to know is , Is this thread safe , will my other threads always get the updated value of this atomic , volatile variable ? I need my other two threads to stop sending data whenever my connection gets broken.

if(ConnectStatus.connected.get()){

   // send data

}

Will the above snippet always work correctly ?

Was it helpful?

Solution

The connection can get bad and disconnected at anytime,so that time , I am making my atomic connected as false. What I would like to know is , Is this thread safe , will my other threads always get the updated value of this atomic , volatile variable ?

Yes and no. First off, your AtomicBoolean should be final and not volatile. AtomicBoolean wraps a volatile boolean but you are not going to be changing it to another AtomicBoolean:

private static final AtomicBoolean connected = new AtomicBoolean(false);

The problem with just using an AtomicBoolean to protect the connection is (as @Jeff mentioned) that even if you test if the connection is connected, it might be disconnected directly afterwards.

if (ConnectStatus.connected.get()) {
   // disconnect happens here, before the send
   // send data
}

You can't protect against this disconnect with an AtomicBoolean. You need to have a lock so that the thread that is disconnecting the connection waits until all sending has been completed:

private final Object lock = new Object();
...
synchronized (lock) {
   if (connected) {
      sendData();
   }
}
...
// this has to wait for the lock to be released before it can be closed
synchronized (lock) {
   if (connected) {
      disconnect();
      connected = false;
   }
}

If you aren't in control of when the connection is disconnected, then you will have to properly catch the exceptions and handle them appropriately.

Lastly, if you need multiple senders, then you should look into a ReentrantReadWriteLock and have your senders lock as a "reader" (funny) which allows multiple readers at a time, and the closing thread lock as a "writer" which allows only one writer at a time.

OTHER TIPS

volatile ensures visibility, so if the connected variable is updated by one thread, it will be visible from another. But, as @Gray points out in his comment ,that's not quite what you are doing. You do not need to use AtomicBoolean if you're not doing atomic compare-and-set operations. If you're just reading or writing a boolean, that is atomic http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html. But, you still have a race condition. What if after you check the get state of connected, the connection drops out?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top