多執行緒返回值的例子
阿新 • • 發佈:2019-02-06
當我們面臨大量資料查詢的時候,在我有限的技術生涯中,想到兩種解決方案。
1.建立專業的solr查詢引擎,實現全文檢索。
2.多執行緒加速查詢的過程。
後臺管理系統,資料量不算大,但是來源較多。較雜。
目前的處理方式是用多執行緒實現。
那麼,問題來了,多執行緒的查詢,關鍵問題在於,傳遞了引數,如何將查詢出的結果返回。
解決方案是採用Callable:
一、一個簡單的demo
package com.test.test; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; public class CallableThread implements Callable<Map<String,Integer>> { //傳遞進來的引數 int data; private Map <String,Integer> map =new HashMap <String,Integer>();//定義需要返回的map private final CountDownLatch latch ; public CallableThread( int data, CountDownLatch latch) { this.data = data; this.latch = latch; } public Map<String,Integer> call() throws Exception { try{ //每個引數手動增加100 data+=100; map.put("data", data); System.out.println("執行緒:"+Thread.currentThread().getName()); }catch(Exception e){ e.printStackTrace(); }finally{ latch.countDown(); } return map; } }
package com.test.test; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class ThreadTest { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(5); ExecutorService pool=Executors.newFixedThreadPool(5); List list=new ArrayList(); try { for(int j=0;j<5;j++){ Callable<Map<String, Integer>> c1 = new CallableThread(j,latch); Future<Map<String,Integer>> f1=pool.submit(c1); list.add(f1); } latch.await(); for(int i=0;i<list.size();i++){ Future<Map<String,Integer>> f1=(Future<Map<String, Integer>>) list.get(i); System.out.println((Integer)f1.get().get("data")); } } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } }
輸出結果:
上述例子,將0-4的值傳遞進入多執行緒,返回的資料是加了100的。證明Callable介面是可以實現資料的返回注意
用法簡要說明:
1.多執行緒類CallableThread實現Callable<Map<String,Integer>> 介面。在該類的成員變數中,定義chua傳遞進來的引數。Callable後接著的泛型Map<String,Integer>代表你需要返回的資料的型別。
2.CountDownLatch用於記錄正在執行的執行緒數量,5個執行緒,那就建立五個CountDownLatch。並且在多執行緒環境內,執行完畢了業務邏輯之後,要呼叫latch.countDown()方法,代表這個執行緒執行完畢了,正在執行的執行緒數減一。
3.多執行緒內部是沒有異常處理機制的。所以,我們一定要記得手動加上try,catch,finally。並且在finally裡面執行latch.countDown();方法,確保執行緒發生異常的情況下,也可以順利地將正在執行的執行緒數減一。否則,如果latch.countDown();得不到執行,你將看不到異常,看不到報錯,程式就一直停留在多執行緒的執行中。
4.當所有執行緒執行完畢之後,在測試方法中執行latch.await();方法,然後批量拿取值即可。返回帶有泛型的Future類。