Java中等待的最佳方式

发布于 2025-01-07 23:53:44 字数 1217 浏览 2 评论 0原文

我有一个应用程序需要等待一段未知的时间。它必须等到服务器完成几个数据字段的填充。

服务器的 API 为我提供了一种请求数据的方法,非常简单...

服务器的 API 还提供了一种接收数据的方法,一次一个字段。它没有告诉我所有字段何时完成填充。

等待服务器完成处理我的请求的最有效方法是什么?这是一些伪代码:

public class ServerRequestMethods {
    public void requestData();
}

public interface ServerDeliveryMethods {
    public void receiveData(String field, int value);
}

public class MyApp extends ServerRequestMethods implements ServerDeliveryMethods {
    //store data fields and their respective values
    public Hashtable<String, Integer> myData;    

    //implement required ServerDeliveryMethods
    public void receiveData(String field, int value) {
        myData.put(field, value);    
    }

    public static void main(String[] args) {
        this.requestData();

        // Now I have to wait for all of the fields to be populated,
        // so that I can decide what to do next.

        decideWhatToDoNext();
        doIt();
    }
}

我必须等到服务器完成填充我的数据字段,并且服务器不会让我知道请求何时完成。所以我必须不断检查我的请求是否已完成处理。做到这一点最有效的方法是什么?

wait() 和notify(),有一个方法保护while 循环,每次我被notify() 唤醒时检查我是否拥有所有必需的值?

Observer 和 Observable,有一个方法可以在每次调用 Observer.Update() 时检查我是否拥有所有必需的值?

最好的方法是什么?谢谢。

I have an app that needs to wait for some unknown amount of time. It must wait until several data fields are finished being populated by a server.

The server's API provides me a way to request data, easy enough...

The server's API also provides a way to receive my data back, one field at a time. It does not tell me when all of the fields are finished being populated.

What is the most efficient way to wait until my request is finished being processed by the server? Here's some pseudocode:

public class ServerRequestMethods {
    public void requestData();
}

public interface ServerDeliveryMethods {
    public void receiveData(String field, int value);
}

public class MyApp extends ServerRequestMethods implements ServerDeliveryMethods {
    //store data fields and their respective values
    public Hashtable<String, Integer> myData;    

    //implement required ServerDeliveryMethods
    public void receiveData(String field, int value) {
        myData.put(field, value);    
    }

    public static void main(String[] args) {
        this.requestData();

        // Now I have to wait for all of the fields to be populated,
        // so that I can decide what to do next.

        decideWhatToDoNext();
        doIt();
    }
}

I have to wait until the server is finished populating my data fields, and the server doesn't let me know when the request is complete. So I must keep checking whether or not my request has finished processing. What is the most efficient way to do this?

wait() and notify(), with a method guarding the while loop that checks if I have all of the required values yet every time I'm woken up by notify()?

Observer and Observable, with a method that checks if I have the all the required values yet every time my Observer.Update() is called?

What's the best approach? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

穿透光 2025-01-14 23:53:45

很老的问题,但我寻找类似的问题并找到了解决方案。
首先,开发人员永远不应该创建一个永远等待的线程。如果您使用“while”循环,您确实必须创建“退出条件”。另外,等待“InterruptedException”也很棘手。如果另一个线程没有调用 yourThread.interrupt() 你将等到程序真正结束。
我使用了 java.util.concurrent.CountDownLatch,简而言之:

/*as field*/
CountDownLatch semaphore = new CountDownLatch(1);

/*waiting code*/
boolean timeout = !semaphore.await(10, TimeUnit.SECONDS);

/*releasing code*/
semaphore.countDown();

结果,“等待代码”线程将等待,直到另一个线程调用“释放代码”或“超时”。如果您想等待填充 10 个字段,请使用“new CountDownLatch(10)”。
这个原理与“java.util.concurrent.Semaphore”类似,但信号量更适合访问锁定,而这确实不是您的情况。

Pretty old question, but I looked for similar problem and found a solution.
At first, developer should never create a thread that will wait forever. You really have to create 'exit condition' if you are using 'while' cycle. Also, waiting for 'InterruptedException' is tricky. If another thread doesn't call yourThread.interrupt() you'll wait until program truly ends.
I used java.util.concurrent.CountDownLatch so in short:

/*as field*/
CountDownLatch semaphore = new CountDownLatch(1);

/*waiting code*/
boolean timeout = !semaphore.await(10, TimeUnit.SECONDS);

/*releasing code*/
semaphore.countDown();

As result, 'waiting code' thread will wait until some another Thread calls 'releasing code' or will "timeout". If you want to wait for 10 fields to be populated, then use 'new CountDownLatch(10)'.
This principle is similar for 'java.util.concurrent.Semaphore' but semaphore is better for access locking and that isn't your case, indeed.

飘然心甜 2025-01-14 23:53:45

似乎很多人(包括我自己)都遇到了麻烦,但我找到了一个简单而时尚的解决方案。使用此方法:

public static void delay(int time) {
    long endTime = System.currentTimeMillis() + time;
    while (System.currentTimeMillis() < endTime) 
    {
        // do nothing
    }
}

获取当前时间并设置结束时间(当前时间 + 等待时间)并等待,直到当前时间达到结束时间。

It seems like many people have been having trouble with this (myself included) but I have found an easy and sleek solution. Use this method:

public static void delay(int time) {
    long endTime = System.currentTimeMillis() + time;
    while (System.currentTimeMillis() < endTime) 
    {
        // do nothing
    }
}

This gets the current time and sets an end time (current time + time to wait) and waits until the current time hits the end time.

有深☉意 2025-01-14 23:53:44

如果我理解正确的话,其他一些线程会调用您的MyApp上的receiveData来填充数据。如果这是正确的,那么你可以这样做:

  1. 你像这样睡觉:

    <前><代码>做{
    this.wait(someSmallTime); //我们正在获取“this”对象的监视器,因此需要通知。你应该花一些时间(比如 100 毫秒)来防止非常罕见但仍然可能发生的死锁,当通知在 this.wait 被调用之前到来时。
    while (!allFieldsAreFilled());

  2. receiveData 应该进行 notify 调用,以unpausewait 调用你的。例如这样:

    myData.put(字段,值);   
    this.notify();
    
  3. 两个块都需要在 this 对象上“同步”,以便能够获取它的监视器(这是 wait 所需要的)。您需要将方法声明为“同步”,或者将相应的块放入 synchronized(this) {...}

If I understood you right, some other thread calls receiveData on your MyApp to fill the data. If that's right, then here's how you do it:

  1. You sleep like this:

    do {
        this.wait(someSmallTime); //We are aquiring a monitor on "this" object, so it would require a notification. You should put some time (like 100msec maybe) to prevent very rare but still possible deadlock, when notification came before this.wait was called.
    } while (!allFieldsAreFilled());
    
  2. receiveData should make a notify call, to unpause that wait call of yours. For example like this:

    myData.put(field, value);   
    this.notify();
    
  3. Both blocks will need to be "synchronized" on this object to be able to aquire it's monitor (that's needed for wait). You need to either declare the methods as "synchronized", or put the respective blocks inside synchronized(this) {...} block.

眼泪淡了忧伤 2025-01-14 23:53:44

我认为最有效的方法是等待和通知。您可以使用 wait() 将线程设置为睡眠状态。您可以使用 notify() 从另一个线程(例如您的服务器)唤醒该线程。 wait() 是一种阻塞方法,您不必轮询任何内容。您还可以使用静态方法Thread.sleep(milliseconds)来等待一段时间。如果你把 sleep 放入一个无限的 while 循环中,检查一个持续等待时间的条件,你也会等待。

我更喜欢 wait()notify(),它们效率最高。

i think the most efficient method is with wait and notify. You can set a Thread into sleep with wait(). You can wake up the Thread from another one, e.g. your server with notify() to wake up. wait() is a blocking method, you dont have to poll anything. You can also use the static method Thread.sleep(milliseconds) to wait for a time. If you put sleep into a endless while loop checking for a condition with a continusly wait time, youll wait also.

I prefer wait() and notify(), its most efficient at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文