![](/img/trans.png)
[英]Costs of Thread.sleep(1) are different depending on busy-loop implementation
[英]Replacing busy loop and sleep in thread
我有一个调用特定服务的线程。 该服务定义了一个回调函数,只要有onProcessing()数据,就可以多次调用该回调函数。
一旦完成,就会调用onCompletion()。
public CallThread implements Runnable{
public boolean isCompleted = false;
public void run(){
ResponseObserver response = new ResponseObserver(){
public void onException(){
//Errors could happen sometimes so the program should just issue another request
}
public void onCompletion(){
isCompleted = true;
//process the result
}
public void onProcessing(){
//This could be called multiple time
}
}
//Service is the object that calls the service
Service service = getService();
while(!isCompleted){
//Request object is populated
Request request = supplyRequest();
service.getDetails(request, response);
//How to remove this sleep
Thread.sleep(10 * 1000);
}
}
}
我创建了一个忙循环,用于检查isCompleted并使其处于睡眠状态。 我现在正在执行的操作是使用sleep命令使该功能能够完成,直到发出下一个请求。
我不确定这是否是最佳选择,因为有时..调用onCompletion()不需要10秒钟。 我只是想让服务返回某些内容,然后再发出另一个请求。
有没有一种方法可以优化我的代码?
CountDownLatch
或CompletableFuture
可用于异步等待条件:
public CallThread implements Runnable {
public boolean isCompleted = false;
@Override
public void run() {
// Try up to 5 calls
for (int i = 0; i < 5; ++i) {
// Create the observer
MyResponseObserver observer = new MyResponseObserver();
// Call the service
service.getDetails(supplyRequest(), observer);
try {
// Wait for the result
Boolean result = observer.completable.get();
// Or wait with a timeout
// observer.completable.get(30, TimeUnit.SECONDS);
// Completed successfully
isCompleted = true;
return;
} catch (ExecutionException e) {
// Completed with exception. Retry.
} catch (InterruptedException e) {
return;
}
}
}
/** Response callback handler */
private static class MyResponseObserver implements ResponseObserver {
/** Result object (change Boolean to the type of your result) */
public final CompletableFuture<Boolean> completable = new CompletableFuture<>();
@Override
public void onException() {
// Signal an error
completable.completeExceptionally(new Exception("Error"));
}
@Override
public void onCompletion() {
// Signal a result
completable.complete(true);
}
@Override
public void onProcessing() {
}
}
}
可能是CountDownLatch
某种组合。 尝试跟随
public class CallThread implements Runnable {
private final CountDownLatch completionLatch = new CountDownLatch(1);
public void run(){
callService();
//Wait without timeout, bad idea
try {
completionLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void callService() {
//Service is the object that calls the service
Service service = getService();
//Request object is populated
ResponseObserver response = new MyResponseObserver(completionLatch);
Request request = supplyRequest();
service.getDetails(request, response);
}
class MyResponseObserver {
private CountDownLatch completionLatch;
MyResponseObserver(CountDownLatch latch) {
this.completionLatch = latch;
}
public void onException(){
/* Retry on exception */
callService();
}
public void onCompletion(){
completionLatch.countDown();
//process the result
}
public void onProcessing(){
//This could be called multiple time
}
};
}
除此之外,您还可以考虑使用Callable
而不是Runnable
因为main
正在等待处理,可能最好在main线程本身中执行。 以下是它的外观
public CallThread implements Callable<MyResult> {
private MyResult myResult;
private final CountDownLatch completionLatch = new CountDownLatch(1);
public MyResult call(){
callService();
//Wait without timeout, bad idea
try {
completionLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return myResult;
}
public setMyResult(MyResult myResult) {
this.myResult = myResult;
}
public void callService() {
//Service is the object that calls the service
Service service = getService();
//Request object is populated
ResponseObserver response = new MyResponseObserver(completionLatch);
Request request = supplyRequest();
service.getDetails(request, response);
}
class MyResponseObserver {
private CountDownLatch completionLatch;
MyResponseObserver(CountDownLatch latch) {
this.completionLatch = latch;
}
public void onException(){
/* Retry on exception */
callService();
}
public void onCompletion(){
completionLatch.countDown();
//process the result
setMyResult(result);
}
public void onProcessing(){
//This could be called multiple time
}
};
}
在main()中
...
FutureTask task = new FutureTask(new CallThead());
new Thread(task).start();
MyResult result = task.get();//blocks thead
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.