我們在使用java多線程編寫相關業務代碼時,往往有這樣一種情況,某個線程依賴於其他線程執行結果。
也就是說,我們需要在一個線程中獲取另一個線程的信息。可以分為兩種情況,一種是輪詢,一種是回調,因為輪詢效率很低,所以本文主要介紹回調方法。
回調的主要思想是:線程run方法執行結束時,主動通知main線程,在main線程中做相應處理。通知main線程可以通過調用main方法中的static方法實現。
假定以下場景:
兩個線程讀取兩個不同文件,最后拼接兩個文件內容輸出。
1、以下是線程代碼:
1 package com.ccg.test; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.InputStreamReader; 7 8 public class CallbackThread implements Runnable{ 9 10 private String fileName; 11 private TestMain callBack; 12 13 public CallbackThread(TestMain callBack,String fileName) { 14 this.fileName = fileName; 15 this.callBack = callBack; 16 } 17 18 @Override 19 public void run() { 20 try { 21 File file = new File(fileName); 22 InputStreamReader in = new InputStreamReader(new FileInputStream(file),"gbk"); 23 BufferedReader br = new BufferedReader(in); 24 String str = br.readLine(); 25 //通知線程調用者run方法執行結果 26 callBack.receiveFileStr(fileName,str); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 } 31 }
可以看到,在run方法結束時回調了線程調用者里面的方法。
2、線程調用者代碼:
1 package com.ccg.test; 2 3 import org.junit.Test; 4 5 public class TestMain { 6 7 @Test 8 public void test() throws InterruptedException{ 9 String f1 = "d:\\a.txt"; 10 String f2 = "d:\\b.txt"; 11 12 TestMain t1 = new TestMain(); 13 TestMain t2 = new TestMain(); 14 15 CallbackThread cb1 = new CallbackThread(t1, f1); 16 CallbackThread cb2 = new CallbackThread(t2, f2); 17 18 new Thread(cb1).start(); 19 new Thread(cb2).start(); 20 } 21 22 public void receiveFileStr(String fileName,String readStr){ 23 StringBuffer sb = new StringBuffer(); 24 sb.append(fileName + ":" + readStr); 25 System.out.println(sb.toString()); 26 } 27 }
執行結果如下:
當然這只是最簡單的應用,jdk1.5之后引入了Callable Executor Future的概念使得多線程編寫代碼更優雅,后面會介紹到。