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