Java中等待的最佳方式
我有一个应用程序需要等待一段未知的时间。它必须等到服务器完成几个数据字段的填充。
服务器的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
很老的问题,但我寻找类似的问题并找到了解决方案。
首先,开发人员永远不应该创建一个永远等待的线程。如果您使用“while”循环,您确实必须创建“退出条件”。另外,等待“InterruptedException”也很棘手。如果另一个线程没有调用 yourThread.interrupt() 你将等到程序真正结束。
我使用了 java.util.concurrent.CountDownLatch,简而言之:
结果,“等待代码”线程将等待,直到另一个线程调用“释放代码”或“超时”。如果您想等待填充 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 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.
似乎很多人(包括我自己)都遇到了麻烦,但我找到了一个简单而时尚的解决方案。使用此方法:
获取当前时间并设置结束时间(当前时间 + 等待时间)并等待,直到当前时间达到结束时间。
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:
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.
如果我理解正确的话,其他一些线程会调用您的
MyApp
上的receiveData
来填充数据。如果这是正确的,那么你可以这样做:你像这样睡觉:
<前><代码>做{
this.wait(someSmallTime); //我们正在获取“this”对象的监视器,因此需要通知。你应该花一些时间(比如 100 毫秒)来防止非常罕见但仍然可能发生的死锁,当通知在 this.wait 被调用之前到来时。
while (!allFieldsAreFilled());
receiveData 应该进行
notify
调用,以unpause
的wait
调用你的。例如这样:两个块都需要在
this
对象上“同步”,以便能够获取它的监视器(这是wait
所需要的)。您需要将方法声明为“同步”,或者将相应的块放入synchronized(this) {...}
块If I understood you right, some other thread calls
receiveData
on yourMyApp
to fill the data. If that's right, then here's how you do it:You sleep like this:
receiveData should make a
notify
call, tounpause
thatwait
call of yours. For example like this:Both blocks will need to be "synchronized" on
this
object to be able to aquire it's monitor (that's needed forwait
). You need to either declare the methods as "synchronized", or put the respective blocks insidesynchronized(this) {...}
block.使用 CompletionService
http://docs. oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CompletionService.html
Use a CompletionService
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CompletionService.html
我认为最有效的方法是等待和通知。您可以使用
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 withnotify()
to wake up.wait()
is a blocking method, you dont have to poll anything. You can also use the static methodThread.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()
andnotify()
, its most efficient at all.