Java之线程池与Lambda表达式


前言

提到线程线程池我们先来说一下线程池的好处,线程池的有点大概可以概括三点:

  • 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。
  • 能有效控制线程池的最大并发数,避免大量线程之间因互相抢夺系统资源而导致的阻塞现象。
  • 能够对线程进行简单的管理,并提供定时执行以及指向间隔循环执行等功能。

1. 线程池的创建

       Java SE 5的java.util.concurrent包中的执行器(Executor)将为你管理Thread对象,从而简化了并发编程。Executor在客户端和任务执行之间提供了一个间接层;与客户端直接执行任务不同,这个中介对象将执行任务。Executor允许你管理异步任务的执行,而无须显式的管理线程的生命周期。Executor是在Java中启动任务的优选方法。
ExecutorService是一个接口,并继承了接口Executor。而Executors是一个工具类,下面来看看它们之间的UML图:
在这里插入图片描述
       其中最为主要的是ThreadPoolExecutor类和Executors中的四类方法,下面我们来逐个分析。

2. ThreadPoolExecutor

       ThreadPoolExecutor是线程池类。对于线程池,可以通俗的将它理解为“存放一定数量的一个线程集合。线程池允许多个线程同时运行,运行同时运行的线程数量就是线程池的容量。当添加到线程池中的线程超过它的容量时,会有一部分线程阻塞等待,线程池会通过相应的调度策略和拒绝策略,对添加到线程池中的线程进行管理。
       对一些关键的变量进行介绍:

  • workers
    workers是HashSet类型,它是一个Worker集合。而一个Worker对应一个线程,也就是说线程池通过workers包含了“一个线程集合”。当Worker对应的线程池启动时,它会执行线程池中的任务;当执行完一个任务后,它会从线程池的阻塞队列中取出一个阻塞的任务来继续运行。workers的作用是:线程池通过它来实现了“允许多个线程同时运行”。

  • workQueue
    workQueue是BlockingQueue类型,它是一个阻塞队列。当线程池中的线程超过它的容量的时候,线程会进入阻塞队列进行阻塞等待。workQueue的作用是:让线程池实现 了阻塞功能。

  • mainLock
    mainLock是互斥锁,通过mainLock实现了对线程池的互斥访问。
    corePoolSize和maximumPoolSize
    corePoolSize是“核心池大小”,maximumPoolSize是“最大池大小”。它们的作用是:调整“线程池中实际运行的线程的数量”。
    例如,当新任务提交给线程池时(通过execute方法)。
    ——如果此时,线程池中运行的线程数量 小于 corePoolSize;则仅当阻塞队列满时才创建新线程。
    ——如果此时,线程池中运行的线程数量 大于 corePoolSize,但却是 小于 maximumPoolSize;则仅当阻塞队列慢时才创建新线程。
    ——如果此时,corePoolSize和maximumPoolSize相同,则创建了固定大小的线程池。如果maximumPoolSize设置为基本的无界值(如,Integer.MAX_VALUE),则允许线程池适应任意数量的并发任务。在大多数情况下,核心池大小和最大池大小的值在创建线程池设置的。但是,也可以使用setCorePoolSize(int)和setMaximumPoolSize(int)进行动态更改。

  • poolSize
    poolSize是当前线程池的实际大小,即线程池中任务的数量。

  • allowCoreThreadTimeOut和keepAliveTime
    allowCoreThreadTimeOut表示是否允许“线程在空闲状态时,仍然能够存活”。
    keepAliveTime表示线程池处于空闲状态的时候,超过keepAliveTime时间之后,空闲的线程会被终止。

  • threadFactory
    threadFactory是ThreadFactory对象,它是一个线程工厂类,即“线程池通ThreadFactory创建线程”

  • handler
    handler是RejectedExecutionHandler类型。它是“线程池拒绝策略”的句柄,也就是说“当某任务添加到线程池中,而线程池拒绝任务是,线程池会通过handler进行相应的处理”

       综上所述,线程池通过workers来管理“线程集合”,每个线程在启动后,会执行线程池中的任务;当一个任务执行完后,它会从线程池的阻塞队列中取出任务来继续运行。阻塞队列时管理线程池任务的队列,当添加到线程池中的任务超过线程池的容量时,该任务就会进入阻塞队列进行等候。

2.1 缓存线程池CachedThreadPool

长度无限制,执行流程为:

  • 判断线程池是否存在空闲线程
  • 存在即使用
  • 不存在,则创建线程,放入线程池,然后使用
  • 创建对象使用Executors.newCachedThreadPool()方法
    代码块如下
public class Executor {
   
    public static void main(String[] args) throws InterruptedException {
   
        ExecutorService service = Executors.newCachedThreadPool();
        service.execute(new Runnable() {
   
            @Override
            public void run() {
   
                System.out.println(Thread.currentThread().getName() + "锄禾日当午");
            }
        });
        service.execute(new Runnable() {
   
            @Override
            public void run() {
   
                System.out.println(Thread.currentThread().getName() + "锄禾日当午");
            }
        });
        service.execute(new Runnable() {
   
            @Override
            public void run() {
   
                System.out.println(Thread.currentThread().getName() + "锄禾日当午");
            }
        });
        Thread.sleep(1000);
        service.execute(new Ru
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值