家蛙树

ThreadPool,Jdk原生线程池,四个参数详细解释原理,当线程池中poolSize达到corePoolSize且阻塞队列已满,再来一个任务,如何处理
 

ThreadPoolExecutor教程在java.util的教程有。

ThreadPoolExecutor参数

        public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              ThreadFactory threadFactory,

                              RejectedExecutionHandler handler)


l  corePoolSize: 线程池里面保持运行的线程数 , 除非设置了 allowCoreThreadTimeOut.


l  maximumPoolSize: 线程池允许的最大的线程数 .


l  keepAliveTime: 当前线程数大于 core时 , 闲置的线程最大的等待新任务来到的时间 ,  超过时间后闲置线程会被关闭。


l  Unit: keepAliveTime的单位 , TimeUnit有定义。


l  workQueue: 任务( Runnable 任务 ,执行 execute 提交的任务)执行前会放在工作队列当中。常用的实现有 LinkedBlockingQueue, ArrayBlockingQueue, PriorityBlockingQueue, SynchronousQueue, 具体区别参考上章节


l  threadFactory, 默认是使用 DefaultThreadFactory 创建线程 .


l  RejectedExecutionHandler handler, 当任务 Executor. execute无法受理 ,例如队列满了等情况则执行 reject handler,  有CallerRunsPolicy(提交任务的线程执行提交的任务 ), AbortPolicy( 中止执行且抛出异常 ), DiscardPolicy( 不处理该任务 ), DiscardOldestPolicy( 抛弃最老的任务再次提交当前任务 ),  默认使用 AbortPolicy.


当前poolSize达到core pool size的时候, 新任务来但是队列满了, 就要看maximumPoolSize了, 如果此时poolSize<maximumPoolSize, 那么会创建新的线程来处理新任务。


 

如果poolSize也达到了maximumPoolSize此时,就会按照RejectExecutionHandler的策略处理新任务。

	public void testThreadPool() throws Exception {
		ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 10, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1));
		//Thread[pool-1-thread-1,5,main] will pend for 99999999
		executor.execute(new PendingTask(99999999L));
		Thread.sleep(1000);
		//99999998L放队列
		executor.execute(new PendingTask(99999998L));
		try {
			//Thread[pool-1-thread-2,5,main] will pend for 99999997
			executor.execute(new PendingTask(99999997L));
			//Thread[pool-1-thread-3,5,main] will pend for 99999996
		    executor.execute(new PendingTask(99999996L));
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		//3
		System.out.println(executor.getActiveCount());
		////99999998L放队列
		System.out.println(((PendingTask)executor.getQueue().peek()).getPendingTime());
	}
	private class PendingTask implements Runnable {
		private long pendingTime = 0;
		public PendingTask(long ms) {
			this.pendingTime = ms;
		}
		public long getPendingTime() {
			return pendingTime;
		}
		public void run() {
			System.out.println(Thread.currentThread() + " will pend for " + this.pendingTime);
			try {
				Thread.sleep(pendingTime);
			}
			catch (Exception e) {
			}
		}
	}

修改maxPoolSize为2则新任务就Reject了。

 

后面加入的任务反而先执行了。。。

java.util.concurrent并发类
发表于:2017-09-22 16:05
状态: 已解决
  问题人
博弈信息界
问题:62 答题:14
心得:0 被赞:0
  答题人
Zealot
问题:2 答题:87
心得:20 被赞:0
支付宝扫码支付