1.线程池
提到线程池就不得不说多线程技术,其主要用于解决处理器单元内多个线程执行的问题,可以显著的减少处理器单元的闲置时间,增加处理器单元的吞吐能力,但其有利弊,使用不当会增加对单个任务的处理时间。
1.1 概念
线程池就是首先创建一些线程,他们的集合称为线程池。线程池在系统启动时就创建大量的空闲线程,程序将一条任务传给线程池,线程池就会启动一条线程来执行任务,执行结束以后该线程不会死亡,而是返回线程池中称为空闲状态,等待执行下一个任务。
1.2 工作机制
1》:在线程池的编辑模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程。如果有就将线程提交给空闲的线程。
2》:一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务
3》:线程池主要是减少丶调整创建和销毁线程而产生的时间段,并且显著减少创建线程的数目。
1.3 使用线程池原因
多线程运行时间,系统不断的启动和关闭新线程,成本非常高,会过度消耗系统资源,以及过度切换线程的危险,从而可能导致系统资源的崩溃,此时线程池的作用会体现出来了,它可以有效处理多个线程的并发问题,避免大量的线程因为互相强占系统资源导致阻塞现象,可以有效降低频繁创建和销毁线程对性能带来的影响
2.浅谈对四种线程的理解
2.1 fixThreadPool 正规线程
我的理解这是一个有指定的线程数的线程池,有核心的线程,里边有固定数量的线程,响应的速度快。正规的并发线程,多用于服务器。固定的线程数由系统资源配置
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
上述方法是只需要指定固定的线程数量即可,工厂类会根据线程数量和Executors中提供的默认线程工厂类来创建固定数量的线程。
核心线程是没有超时机制的,队列没有大小限制,除非线程池关闭了核心线程才会被回收
现在可以分析一下该线程池的工作流程如下:
1、如果当前运行的线程数量少于corePoolSize,则创建新线程来执行任务。
2、在线程池中当前运行的线程数量等于corePoolSize,由于无法在创建新的线程进行任务处理,所以会将任务加入到阻塞队列中进行排队等候处理。
3、当线程池中的线程执行完一个任务后,就会去阻塞队列中循环获取新的任务继续执行。
所以外部线程可以一直提交任务到线程池中阻塞队列中,然后,线程池中的工作线程在获取任务进行执行,这里其实是一个典型的生产者-消费者模式。
2.2 caCheThreadPool 缓存线程池
只有非核心线程,最大线程数很大(Int.Max(values)),它会为每一个任务添加一个新的线程
,这边有一个超时机制,当空闲的线程超过60s没有被用到的话就会被回收,缺点是没有考虑到系统的实际内存大小。
public static ExecutorService newCachedThreadPool(int threads)
{
return newFixedThreadPool(threads,Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}
这种类型的线程池特点是:
1》:工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
2》:如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。
3》:在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。
2.3 singleThreadPool 单线程线程池
看这个名字就知道这个家伙只有一个核心线程,就是一个孤家寡人,通过指定的顺序将任务一个个丢到线程,都乖乖的排队等待执行,不处理并发的操作,不会被回收。确定就是一个人干活效率慢。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
SingleThreadExecutor的corePoolSize和maximumPoolSize被设置为1。其他参数与
FixedThreadPool相同。SingleThreadExecutor使用无界队列LinkedBlockingQueue作为线程池的工
作队列(队列的容量为Integer.MAX_VALUE)。SingleThreadExecutor使用无界队列作为工作队列
对线程池带来的影响与FixedThreadPool相同
2.4 ScheduledThreadPool 调度线程池
这个线程池就比较厉害了,是唯一一个有延迟执行和周期重复执行的线程池。它的核心线程池固定,非核心线程的数量没有限制,但是闲置时会被立即回收
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize/*指定核心线程个数*/);
}
3.总结
1:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2:newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3:newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
4:newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。