手记

JDK中的线程池实现

原理

  • 预创建线程
  • 循环获取队列中的Task
  • 获取Task失败则阻塞等待

创建线程池

ThreadPoolExecutor(int corePoolSize,				//核心线程数
                   int maximumPoolSize,				//最大线程数
                   long keepAliveTime,				//超过corePoolSize的线程,最大存活时间
                   TimeUnit unit,
                   BlockingQueue<Runnable> workQueue,	//任务队列
                   ThreadFactory threadFactory);		//创建线程的工厂

execute方法

分三步

  1. 如果当前线程数<coreSize,创建core线程并执行任务,然后返回.
  2. 向队列中添加任务,如果成功就继续执行。
  3. 如果向队列添加任务失败(任务队列已满),那么就创建非core线程,并执行任务.
if (workerCountOf(c) < corePoolSize) {
   if (addWorker(command, true))
       return;
   c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
   int recheck = ctl.get();
   if (! isRunning(recheck) && remove(command))
       reject(command);
   else if (workerCountOf(recheck) == 0)
       addWorker(null, false);
}
else if (!addWorker(command, false))
   reject(command);

线程执行的run方法

  • 获取Task
  • 成功就执行Task
  • 失败就阻塞或退出
final void runWorker(Worker w) {
	Thread wt = Thread.currentThread();
	Runnable task = w.firstTask;
	w.firstTask = null;
	w.unlock(); // allow interrupts
	boolean completedAbruptly = true;
	try {
		while (task != null || (task = getTask()) != null) {
			w.lock();
			// If pool is stopping, ensure thread is interrupted;
			// if not, ensure thread is not interrupted.  This
			// requires a recheck in second case to deal with
			// shutdownNow race while clearing interrupt
			if ((runStateAtLeast(ctl.get(), STOP) ||
				 (Thread.interrupted() &&
				  runStateAtLeast(ctl.get(), STOP))) &&
				!wt.isInterrupted())
				wt.interrupt();
			try {
				beforeExecute(wt, task);
				Throwable thrown = null;
				try {
					task.run();
				} finally {
					afterExecute(task, thrown);
				}
			} finally {
				task = null;
				w.completedTasks++;
				w.unlock();
			}
		}
		completedAbruptly = false;
	} finally {
		processWorkerExit(w, completedAbruptly);
	}
}

其他相关

  • 如果队列已满,再向其中添加Task时,会先创建非core线程,如果创建成功则执行任务,如果创建失败那么则执行拒绝Handler,JDK中主要有以下几种形式:
AbortPolicy 		抛出一个异常(默认)
CallerRunsPolicy 	在调用线程中执行
DiscardPolicy		丢弃该任务
DiscardOldestPolicy	丢弃之前的任务,并执行现在的任务
  • ScheduledThreadPoolExecutor定时执行任务,继承自ThreadPoolExector,使用专门的延时队列.
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}
0人推荐
随时随地看视频
慕课网APP