java回撥機制用的理解與例項
阿新 • • 發佈:2018-12-12
生活場景如下:
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=");
}
參考文章: