1. 程式人生 > 其它 >詳解java 三種呼叫機制(同步、回撥、非同步)

詳解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。

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

莫聽穿林打葉聲,何妨吟嘯且徐行!!!