Java中ThreadPoolExecutor的參數理解

1、使用Executors建立線程池    

        以前建立線程的時候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()這三個方法。固然Executors也是用不一樣的參數去new ThreadPoolExecutorjava

    1. newFixedThreadPool()函數

    建立線程數固定大小的線程池。 因爲使用了LinkedBlockingQueue因此maximumPoolSize 沒用,當corePoolSize滿了以後就加入到LinkedBlockingQueue隊列中。每當某個線程執行完成以後就從LinkedBlockingQueue隊列中取一個。因此這個是建立固定大小的線程池。this

 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
      this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

   2.newSingleThreadPool()spa

    建立線程數爲1的線程池,因爲使用了LinkedBlockingQueue因此maximumPoolSize 沒用,corePoolSize爲1表示線程數大小爲1,滿了就放入隊列中,執行完了就從隊列取一個。
線程

  public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }


    3.newCachedThreadPool()
code

    建立可緩衝的線程池。沒有大小限制。因爲corePoolSize爲0因此任務會放入SynchronousQueue隊列中,SynchronousQueue只能存放大小爲1,因此會馬上新起線程,因爲maxumumPoolSize爲Integer.MAX_VALUE因此能夠認爲大小爲2147483647。受內存大小限制。繼承

 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

    

2、使用ThreadPoolExecutor建立線程池

ThreadPoolExecutor的構造函數

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

參數:

        一、corePoolSize核心線程數大小,當線程數<corePoolSize ,會建立線程執行runnable隊列

        二、maximumPoolSize 最大線程數, 當線程數 >= corePoolSize的時候,會把runnable放入workQueue中內存

        三、keepAliveTime  保持存活時間,當線程數大於corePoolSize的空閒線程能保持的最大時間。get

        四、unit 時間單位

        五、workQueue 保存任務的阻塞隊列

        六、threadFactory 建立線程的工廠

        七、handler 拒絕策略

任務執行順序:

        一、當線程數小於corePoolSize時,建立線程執行任務。

        二、當線程數大於等於corePoolSize而且workQueue沒有滿時,放入workQueue中

        三、線程數大於等於corePoolSize而且當workQueue滿時,新任務新建線程運行,線程總數要小於maximumPoolSize

        四、當線程總數等於maximumPoolSize而且workQueue滿了的時候執行handler的rejectedExecution。也就是拒絕策略。

ThreadPoolExecutor默認有四個拒絕策略:

        一、ThreadPoolExecutor.AbortPolicy()   直接拋出異常RejectedExecutionException

        二、ThreadPoolExecutor.CallerRunsPolicy()    直接調用run方法而且阻塞執行

        三、ThreadPoolExecutor.DiscardPolicy()   直接丟棄後來的任務

        四、ThreadPoolExecutor.DiscardOldestPolicy()  丟棄在隊列中隊首的任務

固然能夠本身繼承RejectedExecutionHandler來寫拒絕策略.

int corePoolSize = 1;
		int maximumPoolSize = 2;
		int keepAliveTime = 10;
//		BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();
		BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5);
		ThreadFactory threadFactory = Executors.defaultThreadFactory();
		//線程池和隊列滿了以後的處理方式
		//1.跑出異常
		RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); 
		RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy();
		RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy();
		RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy();

		
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler2);
		
		
		for (int j = 1; j < 15; j++) {
			threadPoolExecutor.execute(new Runnable() {
				
				public void run() {
					
					try {
						System.out.println(Thread.currentThread().getName());
						TimeUnit.SECONDS.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					
				}
			});
		}
		
		System.out.println(threadPoolExecutor);
		
	}
相關文章
相關標籤/搜索