簡體   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