詳解java 三種調用機制(同步、回調、異步)


同步調用、回調和異步調用。

同步調用是一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;

 

回調是一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口;

具體說來:就是A類中調用B類中的某個方法C,然后B類中反過來調用A類中的方法D,D這個方法就叫回調方法,

 

異步調用是一種類似消息或事件的機制,不過它的調用方向剛好相反,接口的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的接口)。

多線程是異步處理,異步就意味着不知道處理結果。回調一般是異步處理的一種技術。

 

Future 半異步, 線程+callback 全異步, java8 CompletableFurute 異步回調鏈式編排。

同步回調

下面的例子去掉開啟多線程就是同步回調。

異步回調的使用

1、定義接口

public interface CallBack {
    public void solve(String result);
}

2、主調程序

public class CallbackRequest  implements Callback{
    private CallbackResponse callbackResponse;
    public CallbackRequest(CallbackResponse callbackResponse) {
        this.callbackResponse = callbackResponse;
    }
    //主調需要解決一個問題,所以他把問題交給被調處理,被調單獨創建一個線程,不影響主調程序的運行
    public void request(final String question){
        System.out.println("主調程序問了一個問題");
        new Thread(()->{
            //B想要幫A處理東西,就必須知道誰讓自己處理的,所以要傳入a,也要知道a想處理什么,所以要傳入question
            callbackResponse.handler(this, question);
        }).start();
        //A把要處理的事情交給b之后,就可以自己去玩耍了,或者去處理其他事情
        afterAsk();
    }
    private void afterAsk(){
        System.out.println("主調程序繼續處理其他事情");
    }
    @Override
    public void solve(String result) {
        System.out.println("被調程序接到答案后進行處理" + result);
   }
}

3、被調程序:

public class CallbackResponse {
    public void handler(Callback callback, String request) {
        System.out.println(callback.getClass()+"問的問題是:"+ request);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String result="\n答案是2";
        callback.solve(result);
    }
}

4、測試:

public class CallbackTest {
    public static void main(String[] args) {
        CallbackResponse callbackResponse = new CallbackResponse();
        CallbackRequest callbackRequest = new CallbackRequest(callbackResponse);
        callbackRequest.request("1+1");
    }
}
輸出:
主調程序問了一個問題
主調程序繼續處理其他事情
class javapratice.CallbackRequest問的問題是:1+1
被調程序接到答案后進行處理
答案是2

一句話解釋回調:當前方法有一段邏輯,需要調用者來決定怎么執行。這段邏輯肯定不能寫死,所以需要一個接口,來解耦當前方法和調用者!

 

Java多線程中可以通過callable和future或futuretask結合來獲取線程執行后的返回值。實現方法是通過get方法來調用callable的call方法獲取返回值。

其實這種方法本質上不是回調,回調要求的是任務完成以后被調用者主動回調調用者的接口,而這里是調用者主動使用get方法阻塞獲取返回值。

Callable的使用

1、結合Callable和Future一起使用,通過ExecutorService的submit方法執行Callable,並返回Future。

ExecutorService executor = Executors.newCachedThreadPool();
        Future<String> future = executor.submit(() ->
            {
                System.out.println("call"); TimeUnit.SECONDS.sleep(1); return "str"; } );
//手動阻塞調用get通過call方法獲得返回值。
        System.out.println(future.get());
        //需要手動關閉,不然線程池的線程會繼續執行。
        executor.shutdown();

2、使用futuretask同時作為線程執行單元和數據請求單元

FutureTask<Integer> futureTask = new FutureTask(() ->
       {
            System.out.println("dasds"); return new Random().nextInt(); });
new Thread(futureTask).start(); //阻塞獲取返回值
    System.out.println(futureTask.get());

注:比起future.get(),其實更推薦使用get (long timeout, TimeUnit unit)方法,設置了超時時間可以防止程序無限制的等待future的結果。

 

文章來自:https://www.cnblogs.com/liujiarui/p/13395424.html。

僅僅用來學習,如有侵權,聯系我,馬上刪除。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM