Java 判斷線程池 執行完畢

工作中,遇到很多情況需要使用線程,或者線程池。但往往我們需要等待線程池執行結束後,使用執行結束後的數據做下一步操作。

很多人提供的輪詢,這樣無形增加服務器的壓力。

現在使用JDK 1.5 提供線程池ExecutorService類配合Future接口來實現。 Future接口是Java標準API的一部分,在java.util.concurrent包中。Future接口是Java線程Future模式的實現,可以來進行異步計算

Future模式可以這樣來描述:我有一個任務,提交給了Future,Future替我完成這個任務。期間我自己可以去做任何想做的事情。一段時間之後,我就便可以從Future那兒取出結果。就相當於下了一張訂貨單,一段時間後可以拿着提訂單來提貨,這期間可以幹別的任何事情。其中Future 接口就是訂貨單,真正處理訂單的是Executor類,它根據Future接口的要求來生產產品。

Future接口提供方法來檢測任務是否被執行完,等待任務執行完獲得結果,也可以設置任務執行的超時時間。這個設置超時的方法就是實現Java程序執行超時的關鍵。

Future接口是一個泛型接口,嚴格的格式應該是Future<V>,其中V代表了Future執行的任務返回值的類型。 Future接口的方法介紹如下:

  • boolean cancel (boolean mayInterruptIfRunning) 取消任務的執行。參數指定是否立即中斷任務執行,或者等等任務結束
  • boolean isCancelled () 任務是否已經取消,任務正常完成前將其取消,則返回 true
  • boolean isDone () 任務是否已經完成。需要注意的是如果任務正常終止、異常或取消,都將返回true
  • get () throws InterruptedException, ExecutionException  等待任務執行結束,然後獲得V類型的結果。InterruptedException 線程被中斷異常, ExecutionException任務執行異常,如果任務被取消,還會拋出CancellationException
  • get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 同上面的get功能一樣,多了設置超時時間。參數timeout指定超時時間,uint指定時間的單位,在枚舉類TimeUnit中有相關的定義。如果計算超時,將拋出TimeoutException
  • void shutdown(); //停止線程
  • <T> Future<T> submit(Callable<T> task);

Future的實現類有java.util.concurrent.FutureTask<V>即 javax.swing.SwingWorker<T,V>。通常使用FutureTask來處理我們的任務。FutureTask類同時又實現了Runnable接口,所以可以直接提交給Executor執行。

package Thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TestThread {
    public static void main(String[] args) {
        TestThread t =new TestThread();
        t.Test();
    }
    
    public void Test(){
        ExecutorService executorService = Executors.newFixedThreadPool(10);//線程池的大小
        List<Future<List<Integer>>> results = new ArrayList<Future<List<Integer>>>();//具體創建的線程對象
        for (int i =0; i< 4; i++) {
            ThreadObject v = new ThreadObject(i);
            Future<List<Integer>> result = executorService.submit(v);//執行線程
            results.add(result);//將此線程添加到線程list中
        }
        for(Future<List<Integer>> result : results){
            List<Integer> list = new ArrayList<Integer>();
            try {
                list = result.get();//通過GET 獲取線程的執行結果,如果沒有執行結束,則此get方法會處於等待狀態,知道線程執行結束
            } catch (Exception e) {
            }
            System.out.println(list.toString());
            System.out.println("END");
        }
        executorService.shutdown();//這裏,則線程池中的線程都已經執行完畢了。所以關閉線程池
    }
}

package Thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class ThreadObject implements Callable<List<Integer>>{
    private int i;
    
    public ThreadObject(int i) {
        this.i = i;
        System.out.println("This is " + i);
    }

    @Override
    public List<Integer> call() throws Exception {
        List<Integer> list = new ArrayList<Integer>();
        for (int i =0; i< 10; i++) {
            list.add(i);
            System.out.println(this.i + " Thread: " + i);
            //Thread.sleep(100);
        }
        
        return list;
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章