线程池可以提高我们利用线程的效率,比通过系统频繁的进行线程的创建和销毁要快很多
我们可以在线程池中先创建好多个线程,当要进行使用的时候从线程池中取出来使用,使用完毕放回线程池中以待下次使用
为什么我们从池子中取线程,就比从系统这里创建线程更快更高效呢?
如果是从系统这里创建线程,就需要调用系统api,进一步的由操作系统内核,完成线程的创建,但内核是给所有的进程提供服务的,所以内核什么时候帮你创建线程是不可控的
如果是从线程池这里获取线程,上述在内核中进行的操作,都是提前做好了的,现在取线程的过程,是完全由用户进行控制的,用户想要什么时候获取到线程,就什么时候能够获取到,是可控的
工厂模式概念可以看:工厂模式概念
ExecutorService service1= Executors.newFixedThreadPool(4); //创造一个固定线程数量的线程池
ExecutorService service2=Executors.newCachedThreadPool(); //创建一个线程动态变化的线程池
ExecutorService service3=Executors.newSingleThreadExecutor(); //创建单个线程(比原生的创建线程api更简单一点)
//类似于定时器的效果,添加一些任务,任务都在后续的莫个时刻再执行
//被执行的时候不是只有一个扫描线程来执行任务,可能是由多个线程共同执行所有的任务
ExecutorService service4=Executors.newScheduledThreadPool(4);
//循环1000次,通过submit向线程池中添加1000个任务,线程池中的线程会解决添加到线程中的任务
for(int i=0;i<1000;i++){
service1.submit(new Runnable() {
@Override
public void run() {
System.out.println("hello");
}
});
}
该代码的意思是循环1000次,通过submit向线程池中添加1000个打印“hello”的任务,线程池中的线程会解决添加到线程中的任务。
线程池对象通过调用submit方法来向线程池中添加任务,submit的参数是Runnable类型的对象,通过重写Runnable类型的对象中的run方法来规定添加的任务内容。
ThreadPoolExecutor是最全面的创建线程池的类,Executors工厂类创建线程池是对ThreadPoolExecutor进行进一步封装的(ThreadPoolExecutor创建线程池是原生的,Executors是封装过的)
ThreadPoolExecutor里面的线程个数,并非是固定不变的,会根据当前任务的情况动态发生变化(自适应)
ThreadPoolExecutor executor=new ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue workQueue,ThreadFactory threadfactory,RejectedExecutionHandle handler)
1.corePoolSize核心线程数,至少得有这些线程,哪怕你的线程池一点任务都没有
2.maximumPoolSize最大线程数,最多不能超过这些线程,哪怕你的线程池以及忙冒烟了也不能比这个数目更多
3.keepAliveTime允许线程可以空闲的最大时间数值,TimeUnit是这个时间数值的单位(比如keepAliveTime为3000,TimeUnit为ms,表示3000ms后还没有任务的非核心线程(扩充的线程)就要被销毁,保证了线程池的自适应)
4.workQueue表示一个管理线程池任务的阻塞队列,任务添加到阻塞队列workQueue中,线程去阻塞队列中获取任务进行执行
5.threadfactory表示线程工厂,涉及到工厂模式,通过这个工厂类来创建线程
6.handler表示拒绝方式/拒绝策略,线程池中有一个阻塞队列,当阻塞队列满了以后,继续添加任务,该如何处理?
目前标准库已经提供了四种策略(这四种处理策略是很重要的)
(1).ThreadPoolExecutor.AbortPolicy 当线程池中的阻塞队列满了以后再添加任务就直接抛出异常,线程池就不干活了(相当于新添加的任务不会干,以及阻塞队列中还没有执行的任务也不会干了)
(2).ThreadPoolExecutor.CallerRunsPolicy 谁是添加这个任务的线程,谁就去执行这个任务
(3).ThreadPoolExecutor.DiscardOldestPolicy 丢弃最早的任务,添加新的任务
(4).ThreadPoolExecutor.DiscardPolicy 丢弃掉新的任务