1. 程式人生 > >多執行緒返回值的例子

多執行緒返回值的例子

當我們面臨大量資料查詢的時候,在我有限的技術生涯中,想到兩種解決方案。

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類。