[英]Java, Make a method that can only be called once at a time
I have an application that uses a read write lock to prevent other methods from running when the so called "reconnect" method is called.我有一个应用程序,它使用读写锁来防止在调用所谓的“重新连接”方法时运行其他方法。 Now, I want this "reconnect" method to only be called once at a time.
现在,我希望这个“重新连接”方法一次只被调用一次。 For example, when Thread1 calls "reconnect" and while "reconnect" is executing, Thread2 calls it, it either immediately returns or waits until the call of Thread1 is finished and then returns.
例如,当 Thread1 调用“reconnect”并且“reconnect”正在执行时,Thread2 调用它,它要么立即返回,要么等待直到 Thread1 的调用完成然后返回。 (Resulting in only one execution).
(导致只有一次执行)。 As you can probably imagine I have an application that interacts with some API and when my session times out, it needs to reconnect but I don't want every thread creating a new connection since that would be completely unnecessary.
正如您可能想象的那样,我有一个与某些 API 交互的应用程序,当我的会话超时时,它需要重新连接,但我不希望每个线程都创建一个新连接,因为这完全没有必要。 I hope I provided enough information.
我希望我提供了足够的信息。
Synchronized keyword prevents multiple threads from executing the function at the same time. Synchronized 关键字可防止多个线程同时执行该函数。 Then you just need to check the state of the connection in your method.
然后你只需要在你的方法中检查连接的状态。
public synchronized void reconnect() {
if (!connection.isActive()) { // this method will depend on what type of connection you have
// your code ...
}
}
Essentially you just need reconnect() to be a no-op if the connection is already active.本质上,如果连接已经处于活动状态,您只需要 reconnect() 成为空操作。
It's preferable to maintain a lock object and synchronize on that, such as:最好维护一个锁定对象并对其进行同步,例如:
public class MyClass {
private final Object lock = new Object();
public void reconnect() {
synchronized(lock) {
....
}
}
....
}
The reason is that when you use the synchronized keyword in a method signature, you're actually synchronizing on your MyClass
instance.原因是当您在方法签名中使用 synchronized 关键字时,您实际上是在
MyClass
实例上进行同步。 The problem is, any other code outside your class could also do that.问题是,您班级以外的任何其他代码也可以这样做。 For instance,
例如,
public class SomeOtherClass {
public void go(final MyClass myClass) {
synchronized(myClass) {
wait(Integer.MAXIMUM_VALUE);
}
}
}
Now if some other thread wants to call myClass.reconnect()
, they can't, because SomeOtherClass
has taken the lock on the myClass
instance.现在,如果其他一些线程想要调用
myClass.reconnect()
,他们不能,因为SomeOtherClass
已经锁定了myClass
实例。
I would probably not use a direct lock.我可能不会使用直接锁。
I would use just one thread to handle all the connect/reconnect actions and queue request objects to it.我将只使用一个线程来处理所有连接/重新连接操作并将请求对象排队到它。 This is a little more complex, but:
这有点复杂,但是:
Its more flexible because such a mechansim would allow both synchronous and asynchronous requests/replies.它更灵活,因为这样的机制将允许同步和异步请求/回复。
It's easier to debug because the connect/reconnect only ever happens serially on one thread.调试更容易,因为连接/重新连接只在一个线程上串行发生。
It's easy to add an extra connection to [whatever] if it's ever required or acceptable.如果需要或可以接受,可以很容易地向 [whatever] 添加额外的连接。
Timeouts, keep-alives and connection problems can be detected, and logged/rectified, even if there are no requests outstanding.即使没有未完成的请求,也可以检测并记录/纠正超时、保持连接和连接问题。
Plain hard-locks over operations that may potentially block for an extended time are just too worrying.对可能长时间阻塞的操作的简单硬锁太令人担忧了。
Maybe it's just me... :)也许这只是我... :)
You need a flag and synchronization:您需要一个标志和同步:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.