我有一个应用程序,当调用所谓的"重新连接"方法时,它使用读写锁来阻止其他方法运行。现在,我希望这个"重新连接"方法一次只能调用一次。例如,当Thread1调用"reconnect",而"reconnection"正在执行时,Thread2调用它,它要么立即返回,要么等待,直到Thread1的调用完成,然后返回。(只导致一次执行)。正如你可能想象的那样,我有一个与某些API交互的应用程序,当我的会话超时时,它需要重新连接,但我不希望每个线程都创建一个新的连接,因为这是完全不必要的。我希望我提供了足够的信息。
最好维护一个锁定对象并对其进行同步,例如:
public class MyClass {
private final Object lock = new Object();
public void reconnect() {
synchronized(lock) {
....
}
}
....
}
原因是当在方法签名中使用synchronized关键字时,实际上是在MyClass
实例上进行同步。问题是,类之外的任何其他代码也可以这样做。例如,
public class SomeOtherClass {
public void go(final MyClass myClass) {
synchronized(myClass) {
wait(Integer.MAXIMUM_VALUE);
}
}
}
现在,如果其他线程想要调用myClass.reconnect()
,他们就不能,因为SomeOtherClass
已经锁定了myClass
实例。
Synchronized关键字防止多个线程同时执行函数。然后,您只需要检查方法中的连接状态。
public synchronized void reconnect() {
if (!connection.isActive()) { // this method will depend on what type of connection you have
// your code ...
}
}
从本质上讲,如果连接已经处于活动状态,那么只需要重新连接()就可以了。
我可能不会使用直接锁。
我只使用一个线程来处理所有的连接/重新连接操作和队列请求对象
-
它更灵活,因为这样的机械模拟将允许同步和异步请求/应答。
-
调试更容易,因为连接/重新连接只会发生在一个线程上串行。
-
很容易添加额外的连接到[任何]要求或可接受。
-
可以检测到超时、保持活动状态和连接问题,以及记录/纠正,即使没有未处理的请求。
-
对可能阻止延长时间太令人担忧了。
也许只有我…:)
您需要一个标志和同步:
private boolean mReconnectNeeded;
public synchronized void reconnectIfNeeded() {
if (mReconnectNeeded) {
mReconnectNeeded = false;
// reconnect; if it fails, set the flag again
}
}
public synchronized void setReconnectNeeded() {
mReconnectNeeded = true;
}