线程池的使用:
public static void main(String[] args) {
ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
int andIncrement = mCount.getAndIncrement();
return new Thread(r, "Thread # " + andIncrement);
}
};
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "完成任务");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 10,
200L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(1), sThreadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());
for (int i = 0; i < 200; i++) {
threadPoolExecutor.execute(runnable);
}
}
运行后:
ThreadPoolExecutor构造函数详解:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize:核心线程数,也就是这个线程池一创建就自带多少个线程
maximumPoolSize:最大线程数,就是这个线程池最多能容纳多少个线程
keepAliveTime:设置线程空闲了多长时间后被回收
unit :第三个参数的时间单位
workQueue:设置加入的任务多过corePoolSize时加入的阻塞队列
threadFactory:线程工厂。一般来说就是给线程改个名
handler:拒绝策略。当加入的任务太多,线程池和阻塞队列都塞满的情况下该怎么办
拒绝策略可选:
①ThreadPoolExecutor.AbortPolicy:直接抛出异常
②ThreadPoolExecutor.CallerRunsPolicy:让调用线程池的自己执行任务
③ThreadPoolExecutor.DiscardOldestPolicy:删除老任务,让新任务进来(渣男行为)
④ThreadPoolExecutor.DiscardPolicy:删除新任务(中国好男人)
线程池的执行过程:(以我这个例子为例)
创建一个线程池,自带2个线程,最多装10个线程,线程空闲200毫秒才会被回收,阻塞队列就只能放一个任务,当线程池和阻塞队列都满了的情况下抛弃老任务去执行新任务。
在for循环里一下子塞入200个任务,最终结果是执行了11个任务
注:这里的阻塞队列只能放一个任务的原因是,当阻塞队列满了后线程池才会去创建额外的线程,否则阻塞队列还没满的情况下,执行的线程数一直都是2(核心线程数)。这里我设置一个是作为测试使用,一般是不会这么干的