繁体   English   中英

替换线程的繁忙循环和睡眠

[英]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秒钟。 我只是想让服务返回某些内容,然后再发出另一个请求。

有没有一种方法可以优化我的代码?

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而不是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM