ExecutorService.submit()方法可以有两种入参
1、实现Callable接口的类
2、实现Runnable接口的类
两种 方式的源码其实很类似
public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); return ftask; } public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }他们都返回了一个Future 子类对象(其实都是 FutureTask 对象)这个对象在newTaskFor(task)方法中生成对象;我们可以看到,真正的代码逻辑其实在execute(ftask)方法里,这个execute方法接受一个实现了 Runnable接口的参数。
public void execute(Runnable command) { if (command == null)//任务必须不为null 否则抛异常 throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) {//当前工作线程数 小于 核心线程数 if (addWorker(command, true))//1、尝试加入核心线程池执行任务(执行这一步骤,需要获得全局锁(使用可重入锁)) return;//加入核心线程池成功, 则返回 c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) {//2、尝试加入阻塞队列执行任务 int recheck = ctl.get(); //做一次double-check(1、加入阻塞队列 的时候没有获得全局锁,有可能存在不同步的情况;2、当前的threadPoolExecutor可能调用了shutdown或者shutdownNow方法) if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } //3、尝试加入阻塞队列失败(阻塞队列满了),则继续尝试新建一个线程执行任务(执行这一步骤,需要获得全局锁(使用可重入锁),与 maximumPoolSize 进行比较) else if (!addWorker(command, false)) reject(command);//4、线程数超出maximumPoolSize 则采用饱和策略进行处理 }我们具体来看一下execute方法中的addWorker()方法,该方法是任务加入到线程池中执行的方法;
private boolean addWorker(Runnable firstTask, boolean core) { //balabala... boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { final ReentrantLock mainLock = this.mainLock;//加锁 w = new Worker(firstTask);//把任务封装成Worker对象(Worker类继承了AQS类,Runnable接口) final Thread t = w.thread;//把线程对象指向Worker对象(Worker实现了Runnable接口) if (t != null) { mainLock.lock();//加锁(是一把可重入锁,有独占的特性) //加入到 workers 中 try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. int c = ctl.get(); int rs = runStateOf(c); 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();//Worker对象线程启动,执行任务 workerStarted = true; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; }我们从中可以看到任务被封装成了Worker的对象,t.start()这一句其实启动的是Worker对象这个线程,为什么呢?我们跟到Worker类中去看看吧; private final class Worker extends AbstractQueuedSynchronizer implements Runnable { //balabala... Worker(Runnable firstTask) { setState(-1); this.firstTask = firstTask; //要执行的任务 this.thread = getThreadFactory().newThread(this);//线程指向当前Worker对象 } public void run() { runWorker(this); } //balabala... } Worker类的构造器虽然只传入了一个任务参数,但是下一行将线程指向当前Worker对象,作用就是可以在外部通过调用Worker的属性thread的start方法,从而执行Worker对象本身!!
