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);
		
	}
相关文章
相关标签/搜索