gpt4 book ai didi

java - 该类使用 AtomicBoolean。它是线程安全的吗?

转载 作者:行者123 更新时间:2023-12-02 07:50:32 25 4
gpt4 key购买 nike

我不喜欢用 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 );
}
}
}
  1. 根据我的代码,线程是否安全,如果 2 个线程尝试同时调用 connect(),则只允许一次连接尝试。

  2. 在finally block 中,我连续执行两个AtomicBoolean.set(..),会出现问题,因为在这两个原子调用之间的间隙,某些线程可能会调用_connected .get() 在其他方法中?

  3. 使用_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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com