项目实战-NewFixedThreadPool线程池

简介: 项目实战-NewFixedThreadPool线程池

什么是线程池

       线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。

ff3c40384a0d4988b00ac8a6e4549f48.png

线程池的类型

1.CachedThreadPool

       适合使用在任务量 大但耗时少的任务。

2.FixedThreadPool

       适合使用在任务量比 较固定但耗时长的任务。

3.ScheduledThreadPool

       适合使用在执行 定时任务和具体固定周期的重复任务。

4.SingleThreadPool

       适合使用在多个任务 顺序执行的场景。

5.newWorkStealingPool

       适合使用在很耗 时的任务中。

线程池的好处

1、线程池的重用

       线程的创建和销毁的开销是巨大的,而通过线程池的重用大大减少了这些不必要的开销,当然既然少了这么多消费内存的开销,其线程执行速度也是突飞猛进的提升。

2、控制线程池的并发数

       控制线程池的并发数可以有效的避免大量的线程池争夺CPU资源而造成堵塞。

3、线程池可以对线程进行管理

       线程池可以提供定时、定期、单线程、并发数控制等功能。比如通过ScheduledThreadPool线程池来执行S秒后,每隔N秒执行一次的任务。

线程池的示例

       拿NewFixedThreadPool线程池举例。newFixedThreadPool的特点是他的核心线程数和最大线程数是一致的,并且是一个固定线程数的线程池。线程池的大小一旦达到最大值后,再有新的任务提交时则放入无界阻塞队列中,等到有线程空闲时,再从队列中取出任务继续执行。

1.Client启动类

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * @BelongsProject: demo
 * @BelongsPackage: com.wzl
 * @Author: Wuzilong
 * @Description: 线程池-多线程
 * @CreateTime: 2022-12-30 08:55
 * @Version: 1.0
 */
public class Client {
    public static void main(String[] args) {
        ExecutorService executorService= Executors.newFixedThreadPool(80);
        //构造CountDownLatch传入数量为10000,初始化的计数器大小为1000,与学生数量对应。
        List<String> number=new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            number.add( "少了" +i +"袋牛奶");
        }
        final CountDownLatch latch = new CountDownLatch(number.size());
        //计算1000个学生的学习数据
        for (int i = 0; i <number.size() ; i++) {
            //线程提交任务
            executorService.submit(new DrinkMilk(i,latch,number));
        }
        try{
            //使调用该方法的主线程处于等待状态,当倒数到0时主线程才执行。
            latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException("XXX喝牛奶多线程处理异常",e);
        }
        //关闭线程池
        executorService.shutdown();
    }
}

newFixedThreadPool(80):80指的是线程池的固定大小,根据电脑的配置情况来启动对应的线程数

new DrinkMilk(i,latch,number):将具体业务需要用到的对象或者值通过实例化对象以构造函数的形式传到具体业务类中

CountDownLatch(number.size()):等子线程都执行完毕之后,主线程才继续执行。传入的参数要和执行的线程是一致的

2.具体业务类:实现Runnable接口,并实现了run方法

import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
 * @BelongsProject: demo
 * @BelongsPackage: com.wzl
 * @Author: Wuzilong
 * @Description: 具体业务类
 * @CreateTime: 2022-12-30 08:55
 * @Version: 1.0
 */
public class DrinkMilk implements Runnable {
    int drinkMilkNumber;
    CountDownLatch latch;
    List<String> number;
    public DrinkMilk(int drinkMilkNumber, CountDownLatch latch, List<String> number) {
        this.drinkMilkNumber=drinkMilkNumber;
        this.latch=latch;
        this.number=number;
    }
    @Override
    public void run() {
        this.business();
        latch.countDown();
    }
    private void business(){
        System.out.println("XXX喝了"+drinkMilkNumber+"袋牛奶!"+Thread.currentThread().getName());
    }
}

3.执行结果

b92e760662be4f35955baa144cf6d041.png


目录
打赏
0
0
0
0
6
分享
相关文章
在项目中使用——newFixedThreadPool线程池
在项目中使用——newFixedThreadPool线程池
390 0
【Java 并发编程】线程池机制 ( 线程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor )
【Java 并发编程】线程池机制 ( 线程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor )
145 0
【Java 并发编程】线程池机制 ( 线程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor )
【小家Java】一次Java线程池误用(newFixedThreadPool)引发的线上血案和总结(下)
【小家Java】一次Java线程池误用(newFixedThreadPool)引发的线上血案和总结(下)
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
20天前
|
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
44 17
|
1月前
|
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
54 26
|
3月前
|
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
247 2
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
3月前
|
多线程编程核心:上下文切换深度解析
在现代计算机系统中,多线程编程已成为提高程序性能和响应速度的关键技术。然而,多线程编程中一个不可避免的概念就是上下文切换(Context Switching)。本文将深入探讨上下文切换的概念、原因、影响以及优化策略,帮助你在工作和学习中深入理解这一技术干货。
65 10
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等