1.在分析线程池原理之前,理解线程的创建和销毁是必要前提。
java 提供的新建线程方式有 new Thread(); 但是并不表示创建了一个线程,线程的创建需要向内核系统申请。当调用了Thread的start()方法,才会向系统申请线程。下面是Thread类start()方法的源码,注意start0()方法,是个native方法
通过start0()来申请创建新的线程。
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();//-----------------------------!!!!!!
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
需要知道的是run()方法是一个回调方法,创建完成线程以后再执行。当start()方法结束后线程就会被销毁(执行完run()方法)
2.如何让线程重复使用
下面通过ThreadPool源码来分析
addWorker是execute中的方法,线程池提交的任务会被包装成Worker对象,Worker实现了Runnable接口
private boolean addWorker(Runnable firstTask, boolean core) {
.........//省略代码
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask); // 1
final Thread t = w.thread; // 2
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(); // 3
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
由注释1,2处可知 注释3处的t线程是woker中的线程,那么将会执行Woker的run()方法。下面是构造器
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this); //把自己作为参数
}
Worker的run()方法 中调用了runWorker()
public void run() {
runWorker(this);
}
---------------------------------
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) { //--------
..................//省略代码
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
runWorker()通过循环来取任务 通过getTask()方法。这里也就是说worker的run()方法执行了多个任务,从而实现重复使用。多个任务本来是多个线程run()方法执行,这里实现了一个run()执行多个任务。
3.前面提到run()方法结束,准确来说是start()方法结束,线程就会被销毁,下面分析如何保证不被销毁。
原因就在getTask()
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) { //--------------------------------------------
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
getTask()方法里用了一个死循环获取任务,如果没有任务时,并且没有受到超时和shutdown命令时,线程将会一直被阻塞在这个方法里。从而实现了线程没有被销毁的目的。