1. 优势
线程池的用处:原来是100个任务要有100个线程来执行任务,现在是100个任务我们只要几个线程就可以执行任务了。
一个整合:ThreadPoolExecutor继承了AbstractExecutorService继承了ExecutorService继承了Executor。
package com.roocon.thread.td4;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.TimeUnit;
public class Demo {
public static void main(String[] args) {
//初始化的线程池的大小 最大的线程池的大小 存活的时间 天 阻塞队列 饱和策略
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 50, 10, TimeUnit.DAYS, new ArrayBlockingQueue<>(10),new ThreadPoolExecutor.CallerRunsPolicy());
AtomicInteger count = new AtomicInteger();
for(int i = 0; i < 100 ;i ++) {
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
count.getAndIncrement();
}
});
}
threadPool.shutdown();
while(Thread.activeCount() > 1) {
}
System.out.println(count.get());
}
}
饱和策略,拿到队列第一个任务并执行当前的任务,在构造函数里面传入就可以了。
换个策略,可以把任务执行完毕的。
上面的就是最原始的线程是的使用,接下来我们看下原理:
不是线程的队列,是保存的是等待的执行的任务的队列。
看下属性:
ctl:线程池的状态注意是,ctl是线程池的运行状态。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
我们再看下execute。执行之前我们的约定。
说明:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
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);
}
我们执行的任务会给我们包装成为一个内部类worker。
addWorker
在addWorker调用:
执行runWorker。
runWorker
关闭线程池:
shutDown。
其实就是个标志位
上面的对应:shutdown 和 shutdownNow
shutdownNow:杀掉的很彻底的,统统杀掉了。正在执行的也是杀掉了。