简体   繁体   English

Java,制作一次只能调用一次的方法

[英]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.

相关问题 Java注解和处理器来标记一个方法,以便它只能被调用一次? - Java Annotation and Processor to mark a method as so it can be called once and only once? 如何确保方法只被多个线程调用一次? - How can I make sure a method is only called once by multiple threads? 如何确保仅在给定特定参数的情况下才调用方法 - How to make sure that a method is called only once given specific parameters 使 EJB @Schedule 中的方法只被调用一次 - Make a method inside EJB @Schedule to be called only once paintComponent方法仅被调用一次 - paintComponent method is called only once 我可以在Java中动态调用该方法吗? - Can I make the method dynamically called in Java? Java-使方法在初次启动时仅运行一次 - Java - make a method run only ONCE upon initial startup 有没有办法让一部分 paint() 方法在 Java 中只运行一次? - Is there a way to make a section of the paint() method only run once in Java? 我们如何确保在任何时间仅调用类的静态方法和非静态方法之一? - How can we make sure that at any point of time only one of a static method & a non-static method of a class gets called? Java System.in hasNext 方法仅在第一次调用时有效 - Java System.in hasNext method works only first time it is called
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM