java中线程池的简介及使用方法

本文详细介绍了线程池的概念、优点,以及在并发编程中的应用。讲解了线程池的工作原理,包括任务队列和线程管理,并提供Java中Executors类的使用方法和不同线程池类型(如CachedThreadPool,FixedThreadPool和ThreadPoolExecutor)的创建与配置示例。
摘要由CSDN通过智能技术生成

目录

介绍     

优点

运行原理

线程池的使用流程

基本使用步骤:

代码示例:


介绍     

         线程池是一种并发编程的技术,用于管理和复用多个线程以执行异步任务。它通常由两部分组成:任务队列和一组线程。任务队列用于存储待执行的任务,而线程池则负责管理一组预先创建的线程,这些线程可以从任务队列中获取任务并执行。

优点

线程池的主要优点包括:

  • 降低资源消耗:通过重用线程,避免了频繁创建和销毁线程所带来的开销,从而降低了系统的资源消耗。

  • 提高响应速度:由于线程池中的线程可以立即执行任务,而不需要等待新线程的创建,因此可以更快地响应任务的到达。

  • 控制并发度:通过限制线程池中线程的数量,可以有效控制系统的并发度,防止过多的并发任务导致系统资源的竞争和耗尽。

  • 提高系统稳定性:线程池可以根据系统的负载情况动态调整线程数量,从而使系统在高负载时能够保持稳定运行,而不会因为线程数量不足或过多而导致性能下降或崩溃。

线程池在各种并发编程场景中都得到了广泛应用,例如网络服务器、数据库连接池、线程池等。Java中的java.util.concurrent包提供了丰富的线程池实现,包括ThreadPoolExecutor等。

运行原理

线程池的使用流程

基本使用步骤:

  • 创建线程池:使用Executors类提供的静态工厂方法来创建不同类型的线程池。例如:
  • 提交任务:使用execute()方法提交需要执行的任务给线程池。任务可以是实现了Runnable接口的对象或者实现了Callable接口的对象。
  • 执行任务:线程池会自动管理线程的生命周期,并执行提交的任务。
  • 关闭线程池:在不需要线程池时,需要手动关闭以释放资源。通常使用shutdown()shutdownNow()方法来关闭线程池。
  • 处理任务执行结果:如果任务提交时使用了Callable接口,可以通过Future对象来获取任务的执行结果。

通过合理地配置线程池的大小和参数,可以避免因为线程创建销毁造成的性能开销,并且能够更好地控制并发量,提高系统的稳定性和性能。

代码示例:

   Executors.newCachedThreadPool() 用于创建一个根据需要自动调整线程数量的线程池的方法。它返回一个 ThreadPoolExecutor 实例,这个线程池会根据需要创建新线程,如果有空闲线程可用,就会重用之前创建的线程。如果一个线程在 60 秒内没有被使用,那么它将被终止并从缓存中移除。

    /**
     * 测试方法:演示创建一个缓存线程池,并提交多个任务,最后关闭线程池。
     * 缓存线程池会根据需要创建新线程,如果线程在可重用时间内变为空闲,则可能会被终止并从池中移除。
     */
    @Test
    public void test2() throws ExecutionException, InterruptedException {
        // 创建线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        // 提交三个不同类型的线程任务
        Integer integer = executorService.submit(new CallableTest()).get();  //Callable可以获取返回结果
        executorService.submit(new RunnableTest());
        executorService.submit(new ThreadTest());
        // 关闭线程池,等待所有任务完成
        executorService.shutdown();
    }

   Executors.newFixedThreadPool(5) 是 Java 中用于创建一个固定大小的线程池的方法,其中参数 5 表示线程池中线程的数量为 5。这意味着该线程池最多同时运行 5 个线程,而不会动态地增加或减少线程数量。这种类型的线程池适用于需要限制并发线程数量的场景,比如控制资源的使用,避免因为创建过多线程而导致系统资源耗尽。


    /**
     * 测试方法:演示创建一个固定大小的线程池,并提交多个任务,最后关闭线程池。
     * 固定大小的线程池维护固定数量的线程,在任务过多时会排队等待执行。
     */
    @Test
    public void test3() throws ExecutionException, InterruptedException {
        // 创建一个固定大小为5的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        // 提交三个任务,线程池会根据空闲线程数量来执行这些任务
        Integer integer = executorService.submit(new CallableTest()).get();  //Callable可以获取返回结果
        executorService.submit(new RunnableTest());
        executorService.submit(new ThreadTest());
        // 关闭线程池,等待所有任务完成
        executorService.shutdown();
    }

ThreadPoolExecutor 类用于创建自定义的线程池,它拥有七个参数:

  1. 核心线程数(Core Pool Size): 指定了线程池中保持的最小线程数,即使线程是空闲的。在没有任务执行时,核心线程也不会被回收。在这个例子中,核心线程数为 3。

  2. 最大线程数(Maximum Pool Size): 指定了线程池中可拥有的最大线程数。当有新的任务提交到线程池时,如果当前运行的线程数小于核心线程数,则会创建新线程执行任务。如果当前线程数达到核心线程数,并且任务队列已满,则会创建新线程直到达到最大线程数。在这个例子中,最大线程数为 6。

  3. 空闲线程存活时间(Keep Alive Time): 当线程空闲时间达到此值后,如果线程数超过核心线程数,就会根据存活时间的设置来终止并移除这些空闲线程。在这个例子中,空闲线程存活时间为 60 秒。

  4. 存活时间的单位(Time Unit): 指定了空闲线程存活时间的单位,通常是秒、分钟或小时。在这个例子中,时间单位为秒。

  5. 任务队列(Blocking Queue): 用于存储等待执行的任务的队列。在这个例子中,使用了一个容量为 3 的有界阻塞队列 ArrayBlockingQueue,它会按先进先出(FIFO)的顺序执行任务。此外还可以使用链式阻塞队列作为任务队列,即 LinkedBlockingQueue,它没有固定的容量(理论上是 Integer.MAX_VALUE),可以无限存储任务。

  6. 线程工厂(Thread Factory): 用于创建新线程的工厂。在这个例子中,使用了 Executors.defaultThreadFactory() 来创建默认的线程工厂。

  7. 拒绝策略(Rejected Execution Handler): 当线程池无法执行任务时的处理策略。在这个例子中,使用了 ThreadPoolExecutor.AbortPolicy(),表示当无法执行任务时,会抛出 RejectedExecutionException 异常来拒绝新任务的提交。

自定义的线程池适用于需要灵活控制核心线程数、最大线程数以及任务队列容量的场景。

    /**
     * 测试用例:创建并配置一个线程池执行任务。
     * 本测试用例中,线程池的核心线程数为3,最大线程数为6,空闲线程存活时间为60秒。
     * 线程池使用ArrayBlockingQueue作为任务队列,容量为3。
     * 使用默认的线程工厂创建线程,并且采用AbortPolicy拒绝策略。
     * 向线程池提交三个任务后,关闭线程池。
     */
    @Test
    public void test4() throws ExecutionException, InterruptedException {
        // 创建ThreadPoolExecutor实例,配置各项参数
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                // 核心线程数:线程池一直保持的最小线程数
                3,
                // 最大线程数:线程池可拥有的最大线程数
                6,
                // 空闲线程存活时间:当线程空闲时间达到此值后,如果线程数超过核心线程数,将被终止并移除
                60,
                // 存活时间的单位
                TimeUnit.SECONDS,
                // 任务队列:用于存储等待执行的任务
                new ArrayBlockingQueue<>(3),
                // 线程工厂:用于创建新线程
                Executors.defaultThreadFactory(),
                // 拒绝策略:当线程池无法执行任务时的处理策略
                new ThreadPoolExecutor.AbortPolicy()
        );

        // 向线程池提交三个任务
        Integer integer = threadPoolExecutor.submit(new CallableTest()).get();  //Callable可以获取返回结果
        threadPoolExecutor.submit(new RunnableTest());
        threadPoolExecutor.submit(new ThreadTest());

        // 关闭线程池,等待所有任务完成
        threadPoolExecutor.shutdown();

    }
  • 33
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值