- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不喜欢用 synchronized(this) 锁定我的代码,所以我正在尝试使用 AtomicBooleans。在代码片段中,XMPPConnectionIF.connect() 与远程服务器建立套接字连接。请注意,变量_connecting仅在connect()方法中使用;而 _connected 用于需要使用 _xmppConn 的所有其他方法。我的问题列在下面的代码片段后面。
private final AtomicBoolean _connecting = new AtomicBoolean( false );
private final AtomicBoolean _connected = new AtomicBoolean( false );
private final AtomicBoolean _shuttingDown = new AtomicBoolean( false );
private XMPPConnection _xmppConn;
/**
* @throws XMPPFault if failed to connect
*/
public void connect()
{
// 1) you can only connect once
if( _connected.get() )
return;
// 2) if we're in the middle of completing a connection,
// you're out of luck
if( _connecting.compareAndSet( false, true ) )
{
XMPPConnectionIF aXmppConnection = _xmppConnProvider.get();
boolean encounteredFault = false;
try
{
aXmppConnection.connect(); // may throw XMPPException
aXmppConnection.login( "user", "password" ); // may throw XMPPException
_connected.compareAndSet( false, true );
_xmppConn = aXmppConnection;
}
catch( XMPPException xmppe )
{
encounteredFault = true;
throw new XMPPFault( "failed due to", xmppe );
}
finally
{
if( encounteredFault )
{
_connected.set( false );
_connecting.set( false );
}
else
_connecting.compareAndSet( true, false );
}
}
}
根据我的代码,线程是否安全,如果 2 个线程尝试同时调用 connect(),则只允许一次连接尝试。
在finally block 中,我连续执行两个AtomicBoolean.set(..),会出现问题,因为在这两个原子调用之间的间隙,某些线程可能会调用_connected .get() 在其他方法中?
使用_xmppConn时,我应该执行同步(_xmppConn)吗?
更新在方法中添加了缺少的登录调用。
最佳答案
请记住,使用 3 个 AtomicBoolean 与使用单个锁保护这三个变量不同。在我看来,这些变量的状态构成了对象的单一状态,因此它们应该由同一个锁来保护。在使用原子变量的代码中,不同的线程可以使用原子变量独立更新 _connected
、_connecting
和 _shuttingDown
的状态只会确保对相同变量的访问在多个线程之间同步。
也就是说,我不认为同步 this
是您想要做的。您只想同步对连接状态的访问。您可以做的是创建一个对象用作此状态的锁,而无需获取 this
上的监视器。可视化:
class Thing {
Boolean connected;
Boolean connecting;
Boolean shuttingDown;
Object connectionStateLock = new Object();
void connect() {
synchronized (connectionStateLock) {
// do something with the connection state.
}
}
void someOtherMethodThatLeavesConnectionStateAlone() {
// free range thing-doing, without getting a lock on anything.
}
}
如果您正在使用 Java 进行并发编程,我强烈建议您阅读 Java Concurrency In Practice 。
关于java - 该类使用 AtomicBoolean。它是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/919227/
我是一名优秀的程序员,十分优秀!