线程池:神秘的“轻量级线程”

2023-09-20 16:20:28

当前我们的多线程部分已经学习了几个代码案例:

1.单例模式

2.阻塞队列 -> 生产者消费者模型

3.定时器

4.线程池

而线程存在的意义就是,使用进程来实现并发编程会“太重了”,创建和销毁进程都会比较耗资源。

但是线程会更加高效。此时,使用多线程就可以在很多时候代替进程来实现并发编程了。

但是随着并发程度的提高,随着我们对于性能要求的标准的提高,咱们发现,好像线程也没有那么轻量。

当我们需要频繁创建销毁线程的时候,就发现好像开销还是挺大的~

想要进一步的再提高这里的效率,想出了两种办法:

1.搞一个“轻量级进程” (协程/纤程)(但还没有被加入到Java标准库中)

2.使用线程池(字符串常量池、数据库连接池),来降低创建/销毁线程的开销。

也就是说,现在有一个可以存放线程的池子,事先把需要使用的线程创建好,后面需要使用的时候,直接从池子里去出出来。如果用完了也还给池。(因为这两个动作比创建/销毁更加高效)

创建/销毁线程,是交由操作系统内核完成的,但是从池子里获取/还给池,是咱们自己用户代码就能实现的,不必交给内核操作~

相比于内核来说,用户态,程序执行的行为是可控的,如果要想做某个工作,就会非常干净利落的完成(比如从池子里取、还给池子)

但是如果是通过内核,此时不清楚内核身上背负着多少个任务,无法确定内核都要做哪些工作,整体过程是不可控的~

ExecutorService pool = Executors.newFixedThreadPool(10);

工厂模式:简单的来说,就是用普通的方法,来代替构造方法创建对象~

此处就是构造出一个10个线程的线程池,然后就可以随时安排这些线程帮我们干活了~

线程池提供了一个重要的方法:submit,可以给线程池提交若干个任务

public class testdemo {
    public static void main(String[] args) {

        ExecutorService pool = Executors.newFixedThreadPool(10);

        for(int i = 0 ; i < 1000 ; i++){
            int n = i;
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello" + n);
                }
            });
        }
    }
}      运行程序后发现,main线程结束了,但是整个线程没结束,
       线程池中的线程都是前台线程,此时会组织进程结束~

这段代码中,往线程池放了1000个任务,1000任务就是由这10个线程来平均分配一下,然后再执行打印,差不多是一个线程执行100个(注意这里并非是严格的平均,可能有的多一个,有的少一个)

每个线程都执行完一个打印的任务后,再执行下一个任务,由于每个任务执行时间都差不多,因此 每个线程做的任务数量就差不多~

进一步的可以认为:这1000个任务,就在一个队列中排队,这10个线程,就依次来取队列中的任务,取一个就执行一个执行完了再执行下一个~

问题就来了:

这么简单的代码中,为什么不直接打印的时候打印 i 呢?而是通过 int n = i 这样的操作来完成~

这其中涉及到变量捕获。

 

Executors提供的工厂类

 还有一个包需要我们注意一下:

java.util.concurrent   这个包里放的很多类都是和并发编程(多线程编程密切相关的) 所以这个包也叫做juc

corePoolSize :          核心线程数

maximumPoolSize:最大线程数

ThreadPoolExecutor相当于把里面的线程分为两类:

一类是核心线程(理解为正式员工),一类是临时工(实习生),这俩之和是最大线程数~

同时允许正式员工摸鱼,不允许实习生摸鱼~如果实习生摸鱼太久了,就会被销毁(开除)。

整体的策略,就是正式员工保底,临时工动态调节。

long keepAliveTime: 描述了临时工摸鱼的最大时间

TimeUnit unit : 时间单位(s,ms,分钟)

BlockingQueue<Runnable> workQueue:线程池的任务队列

ThreadFactory threadFactory : 用于创建线程,线程池是需要创建线程的

RejictedExecutionHandler hander : 描述了线程池的“拒绝策略”

实际开发的时候,线程池的线程数,设定成多少合适呢?

并没有具体的数字,要具体情况具体分析,不能说是1.5N、2N(N是cpu的核心数)等等~

更多推荐

.NET网络编程——TCP通信

一、网络编程的基本概念:1.网络就是将不同区域的电脑连接到一起,组成局域网、城域网或广域网。把分部在不同地理区域的计算机于专门的外部设备用通信线路互联成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。2.计算机网络通过传输介质、通信设施和网络通信协议,将地理位置相

git 常用命令有哪些

Git是我们开发工作中使用频率极高的工具,下面总结下他的基本指令有哪些,顺便温习一下。前言一般项目中长存2个分支:主分支(master)和开发分支(develop)项目存在三种短期分支:功能分支(featurebranch)补丁分支(hotfixbranch)预发分支(releasebranch)一旦完成开发,它们就会

Spring MVC拦截器和跨域请求

一、拦截器简介SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。拦截器和过滤器的区别拦截器是SpringMVC组件,而过滤器是Ser

docker系列(8) - docker网络

文章目录8.docker网络8.1四种网络模式8.2常用命令8.3桥接网络模式8.3.1桥接网络模式说明8.3.2桥接网络模式案例8.4host网络模式8.4.1host网络模式说明8.4.2host模式案例8.5none网络模式8.5container网络模式8.5.1container网络模式说明8.5.2cont

Android面试题汇总(二)

一、Java集合1、谈谈Java中List、Set以及Map的区别?List:有序的,数据可以重复。。Set:无序的,数据不能重复。Map:键值对存储。键是唯一的,值不是唯一的。2、谈谈ArrayList和LinkedList的区别?ArrayList:底层是基于数组的,数组占用的是一个连续的内存空间。在新增和删除的时

(面试经典刷题)挑战一周刷完150道-Python版本-第3天(40个题)-I(前10个题)

一、长度最小的子数组给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的连续子数组[numsl,numsl+1,…,numsr-1,numsr],并返回其长度。如果不存在符合条件的子数组,返回0。可以是暴力解法也可以是滑动窗口。可以降低复杂度。classSolut

04JVM_语法糖

一、编译期处理语法糖java编译器把*.java源码编译为*.class字节码的过程中,自动生成和转换的一些代码(添加的class字节码),减轻程序员的负担。1.默认构造器默认构造器没有写任何的构造方法,但经过编译器编译成字节码过程中,会加上调用父类Object的无参构造方法。调用java/lang/Object.”<

浅谈一下前端字符编码

背景众所周知,计算机只能识别二进制,它是由逻辑电路组成,逻辑电路通常只有两个状态,开关的接通与断开,这两种状态正好可以用二进制数的0和1表示。但是现实中存在着其他的字符:数字、字母、中文、特殊符号等。因此就需要将这些字符转化成计算器可以识别的二进制编码。而我们在开发过程中,也常常会遇到各种各样的编码,例如ACSII、u

ChatGPT的未来

随着人工智能的快速发展,ChatGPT作为一种自然语言生成模型,在各个领域都展现出了巨大的潜力。它不仅可以用于日常对话、创意助手和知识查询,还可以应用于教育、医疗、商业等各个领域,为人们带来更多便利和创新。在教育领域,ChatGPT可以成为学生的学习伙伴和辅导员。学生可以通过与ChatGPT的对话,提出问题、寻求解答和

Vue系列(二)之 基础语法【上篇】

目录一.插值1.1文本1.2原始HTML1.3属性1.4表达式二.指令2.1v-if/v-else-if/v-else指令2.2v-show指令2.3v-for指令2.4下拉框/复选框2.5动态参数三.过滤器3.1局部过滤器基本应用3.2局部过滤器串行使用3.3局部过滤器传参3.4全局过滤器四.计算属性和监听属性4.1

【Nginx系列】(一)Nginx基础概念

❝有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top❞首发博客地址文章更新计划系列文章地址Nginx的三个主要应用场景静态资源服务通过本地文件系统提供服务静态资源服务是指通过本地文件系统提供静态文件(如HTML、CSS、JavaScript、图片等

热文推荐