1. 程式人生 > >java回撥機制用的理解與例項

java回撥機制用的理解與例項

生活場景如下:

Wang寫數學題,有一道比較難,需要問Li,Li也不會,要先回家一趟問問老爸怎麼做,這個時候有wang如下三種選擇:

1)一直等待Li回來,期間啥也不幹同步方式

2) 等等再過來看Li回來沒,非同步future方式

3)wang把電話留下來,讓LI回來時打電話給自己非同步callback方式

其中聯絡方式 就是回撥函式,也就是其他人在完成任務後會呼叫的函式

而留下聯絡方式的過程稱為登記回撥函式,也就是要其他人幫自己去做某件事.

先介紹什麼是回撥:

就是A類中呼叫B類中的某個方法C,然後B類在方法c中反過來呼叫A類中的方法D,D這個方法就叫回調方法。

Class A實現介面CallBack——要求1

class A中包含一個class B的引用b ——要求2

class B有一個包含引數CallBack的方法c(CallBack callback) ——要求3

A的物件a呼叫B的方法 c(CallBack callback) ——A類呼叫B類的某個方法 C,同時將a作為引數傳給方法c

然後b就可以在c(CallBack callback)方法中呼叫A的方法d ——B類呼叫A類的某個方法D

回撥介面:

public interface CallBack {
    void solveProblem(String question,String  answer);
}

wang-->類A

public class Wang implements CallBack{

    Li li;

    public Wang(Li li){
        this.li=li;
    }

    // 主執行緒不關心非同步執行的結果
    public void askQuestion(String  question)  {
        System.out.println("wnag:li,"+question);

        // Runnable非同步方式,不等待,不關心返回值
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 注意,這裡吧wang.this也傳了過去
                li.solveAnswer(question,Wang.this);
            }
        }).start();

        System.out.println("wang:我逛街了");

    }

    // 主執行緒關心非同步執行的結果
    public void askQuestion2(String  question) throws ExecutionException, InterruptedException {
        System.out.println("wnag:li,"+question);

        // Callable非同步方式,不等待
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        FutureTask futureTask = new FutureTask(new Callable() {
            @Override
            public Object call() {
                li.solveAnswer(question, Wang.this);
                return null;
            }
        });
        Future<?> future = executorService.submit(futureTask);

        System.out.println("wang:我逛街了");
        // 對非同步回撥返回的結果繼續處理
        Object o1 = future.get();
        System.out.println("wang:根據非同步結果繼續幹活");
    }

    @Override
    public void solveProblem(String question,String answer) {
        System.out.println("wang:"+question+"答案是:"+answer);
    }

}

對wang需要說明的是,askQuestion和askQuestion2兩種實現方式的區別,雖然都是非同步的,但是主執行緒對非同步執行的結果處理不同,askQuestion2中可以獲取對應返回類並進行處理。

Li--->類B

public class Li {

    public void solveAnswer(String question, CallBack callBack){
        // 為了展示非同步效果,所以故意進行延遲
        for(int i=0;i<10000000;i++){

        }
        System.out.println("li: do myself thing");


        String  answer = "";
        if("1+1=".equals(question)){
            answer="2";
        }else{
            answer="no answer";
        }

        System.out.println("li: get answer"+answer);
        callBack.solveProblem(question,answer);
    }
}

呼叫程式碼:

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Li li = new Li();
        Wang wang = new Wang(li);
//        wang.askQuestion("1+1=");
        wang.askQuestion2("1+1=");
    }

參考文章:

https://blog.csdn.net/xiaanming/article/details/8703708