我们为什么使用线程池
首先我们使用new Thread()方法进行创建线程主要时间花销包括创建时间,执行时间,线程切换,销毁时间,当我们整个程序有大量的进程需要我们处理,没有个新的线程都需要这些重复的时间花销,但是我们为什么不在系统一起动就实现准备若干个线程,从而创建和销毁的时间就省去了. 由此我们引入我们的线程池的优势
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {}
corePoolSize
整个线程池核心线程数 也可以理解为整个线程最小保持线程的个数,这个数值最好保持在与CPU核心数保持一直可以通过 Runtime.getRuntime().availableProcessors()方法进行获得
maximumPoolSize
线程池中最大线程数 当我们使用excetore(Runable)提交新任务的时候,即使已有若干空线程,单线程数小于corePoollSize也会创建新的线程来执行提交的任务.
当提交新任务线程数已经大于corePoolSize小于maximumPoolSize但阻塞队列未满不会创建新的线程,而是把线程放入阻塞队列,仅当队列已满才会创建新的线程
通过将corePoollSize和maximumPoolSize设置为相等会创建一个固定大小的线程池,后期可以通过使用setCorePoolSize和setMaximumPoolSize动态更改。
keepAliveTime
当空闲的线程数大于corePoolSize且时间超过keepAliveTime时会进行销毁多余的空闲线程
unit
keepAliveTime的时间单位
workQueue
阻塞队列,当阻塞队列不为空的时候可以使用方法prestartCoreThread或prestartAllCoreThreads预先启动队列中的线程。
线程排队策略: 直接交接(SynchronousQueue) 阻塞队列中只有一个容量,相当于任务直接交付给工作线程,当一直提交任务时因为队列已满就会一直创建新的线程,当线程数等于maximumPoolSize时线程池会启动拒绝策略 无界队列(LinkBlockingQueue,没有容量得链表阻塞队列),当提交任务数大于corePoolSize但是由于是无界队列,队列长度会一直增加下去也会不创建新的线程,
有界队列(ArrayBlockingQueue)可以防止一直创建线程做成内存泄漏,当线程数等于maximumPoolSize时线程池会启动拒绝策略
threadFactory
通过提供不同的 ThreadFactory,您可以更改线程的名称、线程组、优先级、守护程序状态等。
例如
class MyThreadFactory extends AtomicLong implements ThreadFactory
{
@Override
public Thread newThread(Runnable r)
{
Thread t = new Thread(r, "我是线程的妈妈 "+incrementAndGet());
t.setDaemon(true);
return t;
}
}
什么是守护线程 线程分为用户线程,守护线程,守护线程会一直守着用户线程,当用户线程全部结束用户线程也会自动结束,因为没有需要守护的先程了,守护线程也就没必要存在了.
handler
拒绝策略:
AbortPolicy()直接抛出异常):当提交新任务时队列已满也没有工作线程能够接纳时直接抛出异常
CallerRunsPolicy(谁提交的谁运行):当提交新任务时队列已满也没有工作线程能够接纳时谁提交的谁运行新任务
DiscardPolicy(直接抛弃新的任务):当提交新任务时队列已满也没有工作线程能够接纳时直接抛弃新提交的任务
DiscardOldestPolicy(直接抛弃旧任务):当提交新任务时队列已满也没有工作线程能够接纳时直接抛弃队列中最早提交的任务(舍弃队头任务)
使用方法
ArrayBlockingQueue<Runnable> blockQueue = new ArrayBlockingQueue<Runnable>(10);
blockQueue.add(new WorkThread(1 + ""));
blockQueue.add(new WorkThread(2 + ""));
blockQueue.add(new WorkThread(3 + ""));
int coreSize = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(coreSize, coreSize + 10, 2, TimeUnit.MINUTES, blockQueue,new MyThreadFactory() );
threadPool.prestartAllCoreThreads();
}
class MyThreadFactory extends AtomicLong implements ThreadFactory
{
@Override
public Thread newThread(Runnable r)
{
Thread t = new Thread(r, "我是线程的妈妈 "+incrementAndGet());
t.setDaemon(true);
return t;
}
}
|