JavaEE(系列11) -- 多线程案例4(线程池)

news2025/1/11 21:51:17

目录

1. 线程池

2. 创建线程池

2.1 Executors类

2.2 ThreadPoolExecutor类

3. 自己实现线程池


1. 线程池

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

1.那么为什么要有线程池呢?

通俗的来讲,就是将线程提前准备好,创建线程不是直接从系统进行申请,而是从线程池里面拿,等待线程不用了,就放回池里.

  

2.为什么从线程池拿线程要比创建线程快呢?

这就涉及到用户态和内核态

 举例:

2. 创建线程池

2.1 Executors类

这是标准库中提供的创建线程池的方法

  1. 使用 Executors.newFixedThreadPool(10) 能创建出固定包含 10 个线程的线程池.
  2. 返回值类型为 ExecutorService
  3. 通过 ExecutorService.submit 可以注册一个任务到线程池中.
public class ExecutorsTest {
    public static void main(String[] args) {
        // 创建线程池,里面存放10个线程
        ExecutorService pool = java.util.concurrent.Executors.newFixedThreadPool(10);
        // 使用submit往线程池中提交若干的任务
        for (int i = 1; i <= 10; i++) {
            int number = i;
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello"+number);
                }
            });
        }
    }
}

Executors 创建线程池的几种方式

 

  1. newFixedThreadPool: 创建固定线程数的线程池
  2. newCachedThreadPool: 创建线程数目动态增长的线程池.
  3. newSingleThreadExecutor: 创建只包含单个线程的线程池.
  4. newScheduledThreadPool: 设定 延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer.

Executors 本质上是 ThreadPoolExecutor 类的封装. 

2.2 ThreadPoolExecutor类

 

拒绝策略

 最老的这个任务就是最先安排的任务.

代码示例:

public class threadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService pool = new ThreadPoolExecutor(1,3,
                1000, TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>(),
                Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

        for (int i = 0; i < 3; i++) {
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello");
                }
            });
        }
    }
}

3. 自己实现线程池

  • 1. 使用堵塞队列来组织任务
  • 2.实现一个固定线程数数量的线程池
  • 3.使用submit方法,来往堵塞队列添加任务.
package ThreadPool;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * Created with IntelliJ IDEA.
 * Description:手动创建线程池
 * User: YAO
 * Date: 2023-05-18
 * Time: 15:21
 */
public class MyThreadPool {

    // 1.内部使用阻塞队列实现,创建阻塞队列存放执行的任务
    private BlockingDeque<Runnable> queue = new LinkedBlockingDeque<>();

    // 2.创建往线程池推送出任务的方法
    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }

    //3. 创建构造方法,参数为线程的数量
    public MyThreadPool(int n){
        for (int i = 0; i < n; i++) {
            // 3.1 创建线程
            Thread t = new Thread(()->{
                try {
                    while (true){
                        // 此处需要有一个循环,就是无休止的取出,有任务就取出
                        Runnable runnable = queue.take();
                        runnable.run();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            // 3.2 不要忘记启动线程
            t.start();
        }
    }
}

测试自己创建的线程池

package ThreadPool;

/**
 * Created with IntelliJ IDEA.
 * Description:测试自己构建的线程池
 * User: YAO
 * Date: 2023-05-18
 * Time: 15:29
 */
public class MyThreadPoolTest {
    public static void main(String[] args) throws InterruptedException {
        // 1. 创建线程池实例
        MyThreadPool pool = new MyThreadPool(10);
        // 问题2: 当前代码,搞了一个10个线程的线程池,实际开发中,一个线程池的线程设置为多少合适?
            //答案:跟CPU有关系,并不是线程越多越好.不同的程序,线程的工作是不一样的.
            // 1.CPU密集型:主要做一些计算,要在CPU上运行.(此时线程数不应该超过CPU的核心数)
            // 2.IO密集型任务:主要等待IO操作(等待读写硬盘,读写网卡),不咋吃CPU(此时线程数可以远远超过CPU的核心数)
        // 2. 往线程池添加任务
        for (int i = 0; i < 1000; i++) {
            int number = i;
            // 问题1:  为什么需要使用Number进行接收i的值?
                // 答案:lambda表达式(本质就是匿名内部类的写法)具有变量捕获,匿名内部类也有变量捕获!!!!
                // 此处创建Number接收i的值,每一次循环都会创建Number一次,也就是在这个循环里面Number就是不变的,进行下一次循环就重新创建Number
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello" + number);
                }
            });
        }
        Thread.sleep(1000);
    }
}

运行结果

1000个任务传入到阻塞队列,被此线程池的10个线程跑完了.

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/558438.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

百分位数、数据分布、直方图、正态数据分布

目录 1、百分位数 2、数据分布 3、正态数据分布 1、百分位数 统计学中使用百分位数&#xff08;Percentiles&#xff09;提供一个数字&#xff0c;该数字描述了给定百分比值小于的值。 例如&#xff1a;假设我们有一个数组&#xff0c;包含一时刻一条街上人的年龄 arr […

搜索二维矩阵——力扣74

文章目录 题目描述法一&#xff09;一次二分查找法二&#xff09;两次二分查找法三&#xff09;抽象二叉搜索树BST解法 题目描述 法一&#xff09;一次二分查找 首先分析题目&#xff1a;由于①每行的整数从左到右升序&#xff1b;②每行的第一个整数>前一行的最后一个整数&…

AC和AP和STA信息查询

AC和AP和STA信息查询 1、AC的运行统计信息1.1、查看设备的部件类型及状态信息 2、AP的运行统计信息2.1、AP的运行信息 / 查看RU的运行信息2.2、AP性能统计信息2.3、AP的射频信息2.4、AP重启失败的记录2.5、非法AP的存在情况2.6、设备信道切换的记录信息2.7、查看指定AP射频上的…

自助式数据分析工具:jvs-sdw(数据智仓)图表配置说明和实现效果

图表的查询条件配置示例说明 在JVS数据分析图表中&#xff0c;是支持查询条件进行多个数据展示组件的联动查询&#xff0c;实现的方式是设置统一的查询条件&#xff0c;在每个图表组件中&#xff0c;设置对应的查询字段去关联查询条件&#xff0c;那么下面我们逐步介绍配置方式…

CMOS摄像头驱动分析

CMOS摄像头驱动分析 文章目录 CMOS摄像头驱动分析ov2640_probe_dt从设备树中获取ov2640的GPIO引脚并进行初始化v4l2_i2c_subdev_init初始化v4l2子设备v4l2_ctrl_new_std添加vflip控制器 ov2640_probe_dt从设备树中获取ov2640的GPIO引脚并进行初始化 ov2640_probe_dt从设备树中…

设计模式剖析,授之以渔(java代码)

创建型模式 简单工厂模式 public class FoodFactory {public static Food makeFood(String name) {if (name.equals("noodle")) {Food noodle new LanZhouNoodle();noodle.addSpicy("more");return noodle;} else if (name.equals("chicken")…

【论文阅读笔记】BaFFLe: Backdoor Detection via Feedback-based Federated Learning

个人阅读笔记&#xff0c;如有错误欢迎指出 会议&#xff1a;2021 IEEE 41st International Conference on Distributed Computing Systems (ICDCS) BaFFLe: Backdoor Detection via Feedback-based Federated Learning | IEEE Conference Publication | IEEE Xplore 问题&am…

泰克(Tektronix) TCP305A电流探头TCPA300电流放大器

泰克Tektronix TCP305ATCPA300电流放大器 泰克 TCP305 电流探头是一种同时使用变压器和霍尔效应技术的分芯式探头。当通过 TEKPROBE Level II、TekConnect&#xff08;带 TCA-BNC&#xff09;或 TekVPI&#xff08;带 TPA-BNC&#xff09;接口连接到泰克示波器时&#xff0c;泰…

GPU服务器安装Anaconda

1.下载Anaconda安装包&#xff0c;官网地址&#xff0c;清华源地址。 在官网下载到本地之后&#xff0c;可以通过文件传输上传安装包到服务器&#xff0c;使用清华源地址可以直接使用wget下载所需版本&#xff0c;例如&#xff1a; wget https://mirrors.tuna.tsinghua.edu.c…

Hibernate 快速入门

Hibernate 快速入门 〇、前言一、搭建 Hibernate 项目步骤1:新建 Java 项目附录1:新建Java项目中的相关文件信息步骤2:添加 Hibernate 框架支持附录2:添加Hibernate框架支持后,Java项目中的相关文件信息步骤3:其他关键配置1、添加数据库驱动包(本文以MySQL为例)2、配置…

详解C语言assert宏

前言&#xff1a;我们经常在写代码时&#xff0c;发现一些大牛的代码中总有一句assert&#xff08;表达式&#xff09;&#xff0c;经过在网上的学习&#xff0c;笔者也浅显的了解了assert的相关知识&#xff0c;assert一般用于规范代码&#xff0c;避免不必要的错误&#xff0…

【Linux高级 I/O(5)】初识存储映射 I/O——mmap()和 munmap()(附代码示例)

存储映射 I/O 存储映射 I/O&#xff08;memory-mapped I/O&#xff09;是一种基于内存区域的高级 I/O 操作&#xff0c;它能将一个文件映射到进程地址空间中的一块内存区域中&#xff0c;当从这段内存中读数据时&#xff0c;就相当于读文件中的数据&#xff08;对文件进…

【数据库系统设计栗子】——图书借阅简单设计

图书借阅简单设计&#x1f60e; 前言&#x1f64c;需求分析——数据结构1.1图书信息1.2 书库信息1.3 图书库存信息1.4 用户1.5 借阅1.6 借阅记录概念模型E-R图 逻辑模型 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xf…

“三化”引领潮流,时尚代名词

大家好&#xff01;我是微三云小鱼&#xff01; 下面给大家分享一下“潮流文化” 如今越来越多的企业都在向数字化前进 而且也相信数字化代表着 向上、未来还是时尚&#xff0c; 各个企业都希望通过数字化 改变现代管理理念。 希望 像打开云计算一样拓展 另外一个渠道。 除了数…

Redis存在线程安全问题吗?让我们来谈谈!

大家好&#xff0c;我是你们的小米。在之前的文章中&#xff0c;我们谈到了Redis存在的线程安全问题。今天&#xff0c;我将以一个电商项目的实际案例来演示&#xff0c;为大家详细解析Redis线程安全问题的原因&#xff0c;并分享一些具体的解决措施。 为什么存在线程安全问题&…

Java程序设计入门教程--物体的抽象过程

类的概念 面向对象的思想来源于对客观世界的认知。 现实的世界是缤纷复杂、种类繁多&#xff0c;难于认识和理解的&#xff0c;但聪明的人们学会了把这些错综复杂的事物进行分类&#xff0c;从而使世界变得井井有条。比如我们由各式各样的汽车抽象出汽车的概念&#xf…

chatgpt赋能Python-python_label颜色

Python Label 颜色的重要性 在Python编程中&#xff0c;我们经常会使用Label来表示文本标签&#xff0c;并且经常需要为这些标签创建不同的颜色&#xff0c;以区分和凸显关键信息。正确选择和使用标签颜色将有助于提高代码的可读性和可维护性&#xff0c;并且在应用程序和Web开…

云渲染时能否关机或断网?

先说一下云渲染&#xff1a; 基于渲染农场&#xff0c;用户可以将自己制作好的文件打包&#xff0c;通过云渲染客户端将打包文件上传到云渲染的服务器进行渲染。以下是 云渲染中能否关电脑的相关回答&#xff1a; 1.提交、上传文件时可以关电脑吗&#xff1f; 不能。文件提交是…

【敬伟ps教程】颜色和图案的填充

文章目录 油漆桶工具填充命令前景色内容识别图案历史记录黑白灰 渐变图层样式填充填充图层 油漆桶工具 油漆桶工具可以填充前景色和图案&#xff0c;快捷键 G 选好前景色&#xff0c;点击画布&#xff0c;画布就会被填充前景色&#xff1b; 建立选区后&#xff0c;填充会在选…

迅为龙芯2K1000开发板国产处理器操作系统

1、硬件配置 国产龙芯处理器&#xff0c;双核64位系统&#xff0c;板载2GDDR3内存&#xff0c;流畅运行Busybox、Buildroot、Loognix、QT5.12 系统! 2、接口全 板载4路USB HOST、2路千兆以太网、2路UART、2路CAN总线、Mini PCIE、SATA固态盘接口、4G接口、GPS接口WIFI、蓝牙…