替换繁忙循环和线程睡眠



我有一个调用某个服务的线程。 该服务定义了一个可以多次调用的回调函数 只要有数据在处理((。

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);
}
}
}

我创建了一个繁忙的循环,用于检查是否已完成并使其处于睡眠状态。 我现在在做什么..是使用睡眠命令才能完成的功能 直到发出下一个请求。

我不确定这是否是最佳选择,因为有时..不需要 10 秒之前 onCompletion(( 被调用。 我只是希望服务在我发出另一个请求之前返回一些东西。

有没有办法优化我的代码?

可以使用CountDownLatchCompletableFuture异步等待条件:

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而不是Runnablemain因为正在等待处理,可能最好在主线程本身中执行。 下面是它的样子

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
}
};
}

在主((

...
FutureTask task = new FutureTask(new CallThead());
new Thread(task).start();
MyResult result = task.get();//blocks thead

最新更新