并发编程(线程池)

一、前期知识概要

1、设计模式对象池(资源池)

在我们的日常生活我们听过水池,电池等等,水池了用来存放水,电池用来存放电,而在编程的世界中的池是用来存放一组资源

资源池(Resource pool)也叫对象池(Object pool) 被认为是一种设计模式,这里的资源主要是指系统资源, 这些资源不专属于某个进程或内部资源。客户端向池请求资源, 并使用返回的资源进行指定的操作。当客户端使用完资源后, 会把资源放回池中而不是释放或丢弃掉。

总结一句话: 需要时,从池中提取,不用时,放回池中

举个栗子: 对象池就想我们公司的仓库,比如我们去公司上班,公司会给我们提供一个工位,行政人员会给我们提供相应的办公设备,那这个时候她首先会看一下库房中,如果库房中有,直接从库房中拿,如果库房中没有,那就会去网上或者商店购买一个新的。如果员工离职了正常情况下会将员工的能用的办公物品放到库房

设计模式

2、应用场景

它用在当对象的初始化过程代价较大或者使用频率较高时,比如线程池,数据库连接池等。运用对象池化技术可以显著地提升性能。

二、为什么要使用

创建线程对象不像其他对象一样在JVM分配内存即可,还要调用操作系统内核的API,然后操作系统为线程分配一系列的资源,这个成本就很高了。所以线程是一个重量级对象,应该避免频繁创建和销毁

降低资源消耗。 通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

提高响应速度。 当任务到达时,任务可以不需要的等到线程创建就能立即执行。

提高线程的可管理性。 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

引用《Java并发编程的艺术》

三、Java线程池的架构设计

1、说明

Java里面线程池的顶级接口是Executor,该类位于java.util.concurrent,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。

2、重要类说明

类或者接口 说明
ExecutorService 真正的线程池接口。
ScheduledExecutorService 定时任务与线程池功能结合使用
ThreadPoolExecutor ExecutorService的默认实现。重点
ScheduledThreadPoolExecutor 周期性任务调度。

3、结构图

4、Executor

  1. 说明

    Executor接口只有一个execute方法,执行提交Runnable任务,用来替代通常启动线程的方法

  2. 方法

    execute(Runnable r) 
  3. 举个栗子

    /*以前*/ Thread t = new Thread(); t.start(); /*使用线程池*/ Thread t = new Thread(); executor.execute(t) 

5、ExecutorService

  1. 说明

    ExecutorService接口继承自Executor接口,真正的线程池核心类。提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。增加了shutDown(),shutDownNow(),invokeAll(),invokeAny()和submit()等方法。如果需要支持即时关闭,也就是shutDownNow()方法,则任务需要正确处理中断。

  2. 核心方法

    方法名 返回值 说明
    **submit(Callable task) ** Future<T> 提交一个可运行的任务执行,并返回一个表示该任务结果
    submit(Runable task) Future<T> 提交一个可运行的任务执行,并返回一个表示该任务结果
    shutdown() 布尔 阻止新来的任务提交,对已经提交了的任务不会产生任何影响。当已经提交的任务执行完后,它会将那些闲置的线程进行中断,这个过程是异步的
    shutdownNow() List<Runable> 设置线程池的状态为STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表
    isShutdown() 布尔 检测线程池是否正处于关闭中
    isTerminated() 布尔 所有任务在关闭后完成,则返回 true
    awaitTermination() 布尔 定时或者永久等待线程池关闭结束
  3. 举个栗子

     private static int TASK_COUNT = 10; public static void main(String[] args) {
          /*1. 创建线程池对象 */ ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 8, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5)); /*2. 提交任务*/ for (int i = 0; i < TASK_COUNT; i++) {
          pool.execute(() -> {
          System.out
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值