JUC学习-22-源码解读(线程池如何创建线程)

JUC学习-22-线程池如何创建线程

	   executor.execute(new Runnable() {
			@Override
			public void run() {
				System.out.println("1111");
			}
		});

进入到execute 方法体:

 public void execute(Runnable command) {
		if (command == null)
			throw new NullPointerException();
		/*
		 * Proceed in 3 steps:
		 *
		 * 1. If fewer than corePoolSize threads are running, try to
		 * start a new thread with the given command as its first
		 * task.  The call to addWorker atomically checks runState and
		 * workerCount, and so prevents false alarms that would add
		 * threads when it shouldn't, by returning false.
		 *
		 * 2. If a task can be successfully queued, then we still need
		 * to double-check whether we should have added a thread
		 * (because existing ones died since last checking) or that
		 * the pool shut down since entry into this method. So we
		 * recheck state and if necessary roll back the enqueuing if
		 * stopped, or start a new thread if there are none.
		 *
		 * 3. If we cannot queue task, then we try to add a new
		 * thread.  If it fails, we know we are shut down or saturated
		 * and so reject the task.
		 */
		int c = ctl.get();
		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);
	}

当任务数 < 核心线程数 的时候,即使前面的线程已经将任务执行完毕 处于空闲状态,也还是会通过创建新线程的方式 来接受接下来的任务 -> addWorker(command, true)

if (workerCountOf(c) < corePoolSize) 

进入到addWorker(command, true)方法

private boolean addWorker(Runnable firstTask, boolean core) {
		retry:
		for (;;) {
			int c = ctl.get();
			int rs = runStateOf(c);

			// Check if queue empty only if necessary.
			if (rs >= SHUTDOWN &&
				! (rs == SHUTDOWN &&
				   firstTask == null &&
				   ! workQueue.isEmpty()))
				return false;

			for (;;) {
				int wc = workerCountOf(c);
				if (wc >= CAPACITY ||
					wc >= (core ? corePoolSize : maximumPoolSize))
					return false;
				if (compareAndIncrementWorkerCount(c))
					break retry;
				c = ctl.get();  // Re-read ctl
				if (runStateOf(c) != rs)
					continue retry;
				// else CAS failed due to workerCount change; retry inner loop
			}
		}

		boolean workerStarted = false;
		boolean workerAdded = false;
		Worker w = null;
		try {
			w = new Worker(firstTask);
			final Thread t = w.thread;
			if (t != null) {
				final ReentrantLock mainLock = this.mainLock;
				mainLock.lock();
				try {
					// Recheck while holding lock.
					// Back out on ThreadFactory failure or if
					// shut down before lock acquired.
					int rs = runStateOf(ctl.get());

					if (rs < SHUTDOWN ||
						(rs == SHUTDOWN && firstTask == null)) {
						if (t.isAlive()) // precheck that t is startable
							throw new IllegalThreadStateException();
						workers.add(w);
						int s = workers.size();
						if (s > largestPoolSize)
							largestPoolSize = s;
						workerAdded = true;
					}
				} finally {
					mainLock.unlock();
				}
				if (workerAdded) {
					t.start();
					workerStarted = true;
				}
			}
		} finally {
			if (! workerStarted)
				addWorkerFailed(w);
		}
		return workerStarted;
	}

核心代码如下:创建新的线程并且执行start操作

w = new Worker(firstTask);
final Thread t = w.thread;
t.start();

如果此时的线程池中的线程数量 >= 核心线程数,会将新的任务放入到阻塞队列中(线程保活),等到核心线程空闲以后,会执行队列中的任务

	 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);
	}

如果阻塞队列已经满了,会去执行addWorker(command, false),创建新的线程执行任务 -> 线程池是不公平的

如果阻塞队列已经满了,并且线程池中的线程数量已经是最大核心线程数(wc >= (core ? corePoolSize : maximumPoolSize))),会执行拒绝策略

	for (;;) {
				int wc = workerCountOf(c);
				if (wc >= CAPACITY ||
					wc >= (core ? corePoolSize : maximumPoolSize))
					return false;
				if (compareAndIncrementWorkerCount(c))
					break retry;
				c = ctl.get();  // Re-read ctl
				if (runStateOf(c) != rs)
					continue retry;
				// else CAS failed due to workerCount change; retry inner loop
			}
posted @ 2025-07-31 10:27  skystrivegao  阅读(6)  评论(0)    收藏  举报