线程池的使用:
public static void main(String[] args) {ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {int andIncrement = mCount.getAndIncrement();return new Thread(r, "Thread # " + andIncrement);}};Runnable runnable = new Runnable() {@Overridepublic 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 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(核心线程数)。这里我设置一个是作为测试使用,一般是不会这么干的