Executor framework的機制

從java5開始,java就提供了名叫Executor framework的機制,主要是圍繞着Executor接口, 它的接口 ExecutorService, 以及實現了這兩個接口的ThreadPoolExecutor類來展開,這種機制把線程的執行和創建分離開了,你只需要創建一個線程,然後把線程丟給Executor,讓它執行去吧。使用這個機制的另外一個好處是可以使用Callable接口,它類似於Runnable接口,但是有兩個不一樣的特性。
  • 它的主要方法是call(), 它可以攜帶一個返回值。
  • 當你發送了一個Callable對象給executor之後,你可以拿到一個實現了Future接口的對象,通過這個對象,你可以控制對象的狀態以及Callable對象的結果。

package threadPool.executorDemo;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * 
 * 類似於Runnable接口,具有以下特點
 * 1 它的主要方法是call(), 它可以攜帶一個返回值。
 * 2 當你發送了一個Callable對象給executor之後,
 * 你可以拿到一個實現了Future接口的對象,通過這個對象,你可以控制對象的狀態以及Callable對象的結果。
 * 
 * 3 Callable 接口類似於 Runnable,兩者都是爲那些其實例可能被另一個線程執行的類設計的。
 * 但是 Runnable 不會返回結果,並且無法拋出經過檢查的異常。 
 * @version  [版本號, 2014-3-10]
 * @see  [相關類/方法]
 * @since  [產品/模塊版本]
 */
public class FactorialCalculator implements Callable<Integer> {
    
    private Integer number;
    
    public FactorialCalculator(Integer number) {
        this.number = number;
    }
    
    @Override
    public Integer call() throws Exception {
        int result = 1;
        if ((number == 0) || (number == 1)) {
            result = 1;
        }
        else {
            for (int i = 2; i <= number; i++) {
                result *= i;
                TimeUnit.MILLISECONDS.sleep(50L);
            }
        }
        System.out.printf("%s: %d\n", Thread.currentThread().getName(), result);
        return result;
    }
}

package threadPool.executorDemo;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

public class TestDemo3 {
    
    /** 
     * 數的階乘 n!
     * <功能詳細描述>
     * @param args
     * @see [類、類#方法、類#成員]
     */
    public static void main(String[] args) {
        //創建了兩條線程
        ThreadPoolExecutor pool = (ThreadPoolExecutor)Executors.newFixedThreadPool(2);
        
        //添加線程池關閉後出現的異常處理
        pool.setRejectedExecutionHandler(new RejectedTaskController());
        
        //用於存放Future接口的對象容器
        List<Future<Integer>> resultList = new ArrayList<Future<Integer>>();
        
        FactorialCalculator calculator = new FactorialCalculator(6 );
        
        //提交一個返回值的任務用於執行,返回一個表示任務的未決結果的 Future
        //Future接口 表示異步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,並獲取計算的結果
        Future<Integer> result = pool.submit(calculator);
        resultList.add(result);
        
        FactorialCalculator calculator1 = new FactorialCalculator(5);
        Future<Integer> result1 = pool.submit(calculator1);
        resultList.add(result1);
        
        for (int i = 0; i < resultList.size(); i++) {
            result = resultList.get(i);
            Integer number = null;
            try {
                //如有必要,等待計算完成,然後獲取其結果
                number = result.get();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            catch (ExecutionException e) {
                e.printStackTrace();
            }
            System.out.printf("Main: Task %d: %d\n", i, number);
        }
        //關閉線程池
        //按過去執行已提交任務的順序發起一個有序的關閉,但是不接受新任務
        pool.shutdown();
    }
    
}

package threadPool.executorDemo;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 
 * 當線程池關閉後,用來處理線程異常
 * <功能詳細描述>
 *
 * @version  [版本號, 2014-3-10]
 * @see  [相關類/方法]
 * @since  [產品/模塊版本]
 */
public class RejectedTaskController implements RejectedExecutionHandler {
    
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        
        //打印線程信息
        System.out.printf("RejectedTaskController: The task %s has been rejected\n", r.toString());
        
        //打印線程池信息
        System.out.printf("RejectedTaskController: %s\n", executor.toString());
        
        //如果此執行程序處於在 shutdown 或 shutdownNow 之後正在終止但尚未完全終止的過程中,則返回 true
        System.out.printf("RejectedTaskController: Terminating: %s\n", executor.isTerminating());
        
        //如果關閉後所有任務都已完成,則返回 true
        System.out.printf("RejectedTaksController: Terminated: %s\n", executor.isTerminated());
    }
}


 


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