当前位置: 首页 > article >正文

【JAVA入门】Day48 - 线程池

【JAVA入门】Day48 - 线程池


文章目录

  • 【JAVA入门】Day48 - 线程池
    • 一、线程池的主要核心原理
    • 二、自定义线程池
    • 三、线程池的大小


        我们之前写的代码都是,用到线程的时候再创建,用完之后线程也就消失了,实际上这是不对的,它会浪费计算机的内存和运算资源。
        线程池的出现就是为了解决这个问题,线程池在收到任务后,会派出一个空闲线程进行处理,处理完毕后,该线程又会回到线程池;如果没处理完时又来了新的任务,那么它就再派出一个线程进行处理,但最后,所有的线程都会再次回到线程池,没有产生任何浪费。
        线程池虽然方便,但也是有上限的,这个上限可以由我们自己设置,如果提交任务时池子里没有空闲线程,剩下的线程只能在外等待。

一、线程池的主要核心原理

① 创建一个池子,池子中是空的。
② 提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子。下次再提交任务时,不需要创建新的线程,直接复用已有的线程即可。
③ 如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待。

如果要用代码创建线程池,我们需要用到一个新的工具类——Executors。
在这里插入图片描述

代码实现如下:

package ExecutorsDemos;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyThreadPoolDemo {
    public static void main(String[] args) {
        /*
            public static ExecutorService newCachedThreadPool()                     创建一个没有上限的线程池
            public static ExecutorService newFixedThreadPool(int nThreads)          创建一个上限为nThreads的线程池
         */

        //1.获取线程池对象
        ExecutorService pool1 = Executors.newCachedThreadPool();

        //2.提交任务
        pool1.submit(new MyRunnable());
        pool1.submit(new MyRunnable());
        pool1.submit(new MyRunnable());
        pool1.submit(new MyRunnable());
        pool1.submit(new MyRunnable());

        //3.销毁线程池
        //pool1.shutdown();

        //4.创建一个有上限的线程池
        ExecutorService pool2 = Executors.newFixedThreadPool(3);
      
    }
}

二、自定义线程池

        线程池创建的构造方法 ThreadPoolExecutor() 最多可达7个参数。如果将线程池比作经营饭店,那么这七个参数对应下面七种要素。
在这里插入图片描述
        自定义线程池的运行情况和你提交的任务数量有关,假设有一个自定义线程池,核心线程有3个,临时线程有3个,现在根据不同任务数量进行处理。
1.提交3个任务,线程池只需动用3个核心线程分别执行即可。
在这里插入图片描述

2.提交5个任务时,此时前3个任务分别被3个核心线程包揽,但是剩下两个任务并没有核心线程可以支持,这时候线程池却不创建临时线程来干活,因此后2个任务只能排队等待。

在这里插入图片描述
3.提交8个任务时,此时前3个任务被3个核心线程包揽,然后剩下3个任务去队列里排队,把长度为3的队列也占满了,此时还有2个任务没有去处,这个时候线程池才会创建2个临时线程来处理任务七和任务八。
在这里插入图片描述
由这个案例可以知道,先提交的任务不一定优先执行。
4.提交10个任务时,前3个任务被3个核心线程包揽,后3个任务被放入队伍排队,再3个任务被临时线程包揽,此时还剩1个任务,此时这个任务没有线程可以处理,只能触发任务拒绝策略。

在这里插入图片描述
Java 中默认的策略就是:丢弃任务并抛出异常,其他三个策略了解一下就行。
在这里插入图片描述

        自定义线程池的构造方法代码实现如下所示:

package ExecutorsDemos;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorDemo1 {
    /*
        ThreadPoolExecutor
        参数一:核心线程数量
        不能小于0
        参数二:最大线程数
        不能小于等于0,最大数量>=核心线程数量
        参数三:空闲线程最大存活时间
        不能小于0
        参数四:时间单位
        用TimeUnit指定
        参数五:任务队列
        不能为null
        参数六:创建线程工厂
        不能为null
        参数七:任务的拒绝策略
        不能为null
     */
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3, //核心线程数量,不能小于0
                6,  //最大线程数,不能小于0,最大数量 >= 核心线程数
                60,  //空闲线程最大存活时间
                TimeUnit.SECONDS,   //时间单位,这里是一个常量"秒"
                new ArrayBlockingQueue<>(3),    //阻塞队列,长度为3
                Executors.defaultThreadFactory(),     //创建线程工厂
                new ThreadPoolExecutor.AbortPolicy()  //任务的拒绝策略,它是一个内部类
        );
    }
}

三、线程池的大小

        线程池多大合适呢?这个我们一般有专门的公式。
在这里插入图片描述
        一个4核8线程的CPU,最大并行数是8。
在这里插入图片描述


http://www.kler.cn/a/313624.html

相关文章:

  • 从社交媒体到元宇宙:Facebook未来发展新方向
  • css:盒子模型
  • 使用pdfjs加载多页pdf并实现打印
  • Java 网络编程(一)—— UDP数据报套接字编程
  • 【Spring】@Autowired与@Resource的区别
  • 翼鸥教育:从OceanBase V3.1.4 到 V4.2.1,8套核心集群升级实践
  • 《使用 LangChain 进行大模型应用开发》学习笔记(五)
  • elasticsearch同步mysql方案
  • 独立站技能树/工具箱1.0 总纲篇丨出海笔记
  • Centos7更换阿里云的 YUM 镜像仓库
  • K8S - Access Control 机制介绍
  • Oracle11g安装配置详细教程
  • [数据集][目标检测]智慧交通铁轨裂缝检测数据集VOC+YOLO格式4类别
  • 关于网络、模型、算法的一些理论知识补充(重新在概念上定义自己研究的方向!!!)
  • 多目标优化算法求解LSMOP(Large-Scale Multi-Objective Optimization Problem)测试集,MATLAB代码
  • go testing 包
  • Python Web 中间件开发与优化指南
  • Java项目实战II基于Java+Spring Boot+MySQL的校园社团信息管理系统(源码+数据库+文档)
  • VMware安装rustdesk服务器
  • 堆的向下调整算法和TOPK问题
  • 互联网应用安全
  • mongodb 主从集群,分片集群
  • 深入浅出通信原理
  • 一些面试问题
  • Go 语言的垃圾回收机制
  • 【JavaScript】数据结构之字典 哈希表