请问挥发性的&原子始终确保线程安全

时间:2013-09-19 20:51:15

标签: java multithreading concurrency thread-safety java.util.concurrent

每当我寻找并发访问时,我都会得到混合答案,我已经订购了JCIP书并且已经开始了,但是我想确定我的这个并发基础知识,这是我的方案

我有3个帖子。一个线程负责建立连接并创建一个单独的连接对象实例。另外两个线程将不断发送数据。

现在其他线程将在CountDownLatch上等待,一旦建立连接,连接线程将把它倒计数到零。

以下是我在ConnectStatus课程中声明的内容,希望connected变量同步并且对所有主题都可见。

public class ConnectStatus {

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

}

我使用的是connected变量,它是易变的&原子来维持连接状态。这样其他线程在发送数据之前就可以“始终”知道连接是否处于活动状态。

一旦建立连接,我将此布尔值设为true并将其锁定为零。

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

现在其他线程将被锁存器通知,并且原子值也将为true,并且线程开始发送数据。

在下面发送数据线索片段。

if(ConnectStatus.connected.get()){

   // send data

}

现在这是我的问题,连接可能随时变坏并断开连接,所以那个时候,我将原子connected视为假。我想知道的是,这个线程是否安全,我的其他线程是否总是得到这个原子,易变量的更新值?我需要另外两个线程在我的连接断开时停止发送数据。

if(ConnectStatus.connected.get()){

   // send data

}

上述代码段是否始终正常运行?

2 个答案:

答案 0 :(得分:3)

  

连接可能随时变坏并断开连接,所以那个时候,我将原子连接为假。我想知道的是,这个线程是否安全,我的其他线程是否总是得到这个原子,volatile变量的更新值?

是和否。首先,您的AtomicBoolean应该是final不是 volatileAtomicBoolean包裹volatile boolean,但您不会将其更改为其他AtomicBoolean

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

仅使用AtomicBoolean来保护连接的问题是(如@Jeff所提到的),即使您测试连接是否已连接,也可能会在之后直接断开连接。

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

您无法使用AtomicBoolean防止此断开连接。您需要有一个锁,以便断开连接的线程等待,直到所有发送完成:

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;
   }
}

如果在连接断开时无法控制,则必须正确捕获异常并正确处理它们。

最后,如果您需要多个发件人,那么您应该查看ReentrantReadWriteLock并让您的发件人锁定为“读者”(有趣),一次允许多个读者,并将结束线程锁定为“作家”,一次只允许一位作家。

答案 1 :(得分:2)

volatile确保可见性,因此如果connected变量由一个线程更新,则它将从另一个线程可见。但是,正如@Gray在他的评论中指出的那样,这并不是你正在做的事情。如果您没有进行原子比较和设置操作,则无需使用AtomicBoolean。如果您只是阅读或撰写boolean,那就是原子http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html。但是,你仍然有竞争条件。如果您检查get connected状态后,连接会断开怎么办?