线程池,以及线程池的实现以及面试常问的问题,工厂模式,常见的锁策略(面试常考,要了解,不行就背)

一、💛

线程池的基本介绍

内存池,进程池,连接池,常量池,这些池子概念上都是一样的~~

如果我们需要频繁的创建销毁线程,此时创建销毁的成本就不能忽视了,因此就可以使用线程池。

提前创建好一波线程,后续需要使用线程,就直接从池子里面拿一个即可,当线程不再使用,就放回池子里面。(本来是需要创建线程/销毁线程,现在是从池子里面获取到现成的线程,并且把线程归还到池子里面

那么为啥从池子里面拿就比系统里面创建线程更加高效呢?

不用线程池:如果是系统这里创建线程,需要调用系统API,进一步的由操作系统内核完成,完成线程的创建过程(内核是给所有进程提供服务的,这样你想干的事情,就需要等一等,等多长时间我们是未知的,是不可以控制的)

使用线程池:上述的内核中进行的操作都是提前做好了的,现在的取线程过程,纯粹的是用户使用代码完成的(纯用户态)-是可控制的。

二、💙

工厂模式:去生产的功能(字面意思),用于生产对象,一般情况下我们创建对象都是new,通过构造方法,但是构造方法有时候存在巨大的缺陷(构造方法是固定就是类名,有的类需要使用多种不同构造方式->(方法重载仅要求参数的个数和类型有区别)

~比如说:表示坐标->这种无法构成重载

public class Circle {public Circle(double x,double y){         //笛卡尔坐标};public  Circle(double r,double a){        //极坐标};
}
所以上面的代码也不对,构不成方法重载

使用工厂模式来解决上述问题,不使用构造方法来,(我刚开始也在想为什么是静态,直到我自己去试一下,明白了也就是说不用构造方法创建对象,假如不是静态方法,那么该怎么调用他呢,不是静态的,可是只能用对象.方法才可以调用)用普通方法来构造对象,这样方法就可以任意的了,普通方法内部去new对象~由于普通方法的目的是创建对象,然后调用方法来设置属性,所以方法一般都是静态的。(类名.方法)

三、💜 

//Executors:工厂类,后面的是工厂方法。这句话是创建一个固定线程数量的线程池
//线程池对象:ExecutorService serviceExecutorService service= Executors.newFixedThreadPool(4);
//创建一个线程数组,动态变化的线程池。ExecutorService service2= Executors.newCachedThreadPool();
//包含单个线程(比原生创建API更简单一些指Thread)ExecutorService service3= Executors.newSingleThreadExecutor();
//类似于定时器效果,添加一些任务,执行,被执行的时候,不是只有有一个扫描线程来执行,可能是有多个共同执行ExecutorService service4= Executors.newScheduledThreadPool();}

 

四、❤️

面试题:谈谈java库中的线程池构成方法的参数和含义

这个方法最复杂,而且别的参数这个参数都有,所以就只解释这个方法就行。

int corePoolSize:核心线程数

int maximunPoolSize:最大线程数

ThreadPoolExcutor:里面的线程个数,并

非固定不变的,会根据当前任务的情况动态变化(自适应)

corePoolSize:至少要这些线程,哪怕你的线程都没任务也要这些个线程(如同公司里面的正式员工)

maximumPoolSize:最多不超过这些线程,哪怕干冒烟了,也不能比这个更多了(正式员工+实习生)

long keepAliveTime, TimeUnit unit:实习生线程,空闲时间超过指定阈值(允许实习生摸鱼的最大时间),就可以销毁了

BlockingQueue<Runnable>workQueue:线程池内部有很多很多,任务可以使用阻塞队列管理,线程池可以内置阻塞队列,也可以手动一个。

RejectedExecutionHandler   handler:线程池考的重点,拒绝方式/拒绝策略,线程池有一个阻塞队列,当队列满了,继续加任务如何处理。

1.ThreadPoolExecutors.AbortPolicy:直接抛出异常,线程池就不干活了,(小王喊我打球,我在学习,我直接崩溃了,我哇哇大哭)

2.ThreadPoolExecutor.callerRunsPolicy:谁说添加这个任务的线程,谁就去执行这个任务

,我会直接说:我没空,自己投去吧)

3.ThreadPoolExecutor.DiscardPolicy:把新的任务丢弃,(不打球了,我接着学习)

4.ThreadPoolExecutor.DiscardPolicy:丢弃最早的任务,执行新的任务(放弃学习,去打球)

有的线程公司会推荐使用这个。

 

五、💚 

具体实现一个线程池

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;class MyThreadPool {private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();//通过这个方法把任务添加到线程池中public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}//n表示一个线程池里面有几个字段,创建了一个固定数量的线程池public MyThreadPool(int n) throws InterruptedException {for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {while (true) {Runnable runnable = null;try {runnable = queue.take();      //从队列中提取这个任务} catch (InterruptedException e) {e.printStackTrace();}runnable.run();                  //运行这个任务}});t.start();                              //开启这个线程}}
}
public class Demo4 {public static void main(String[] args) throws InterruptedException {//获取当前引用实例MyThreadPool myThreadPool = new MyThreadPool(4);for (int i = 0; i < 1000; i++) {               //循环很关键哈,这个循环是添加1000次任务,但是假如你放到run里面,就会变成一个任务,至少内容是执行1000遍,线程是执行多个任务,但是不能一个任务还分担myThreadPool.submit(new Runnable() {           //(安排任务,安排一个任务)@Override                                  //这个任务进行的工作public void run() {System.out.println(Thread.currentThread().getName() + " love");}});}}
}

面试问题2号:创建线程池的时候,线程个数怎么数的:

网路上查资料很多:假设cpu逻辑数是N,线程的个数:N,N+1,2N···

准确的说都不准确,因为不同的项目要做的工作是不同的:

cpu密集型线程工作:全是运算大部分工作在cpu上完成,cpu给他安排核心,才能概括,假如cpu N个核心,线程数量最好也是为N,如果多了,线程也只能是排队等待,没有新的进展

Io密集型线程工作:涉及大量等待时间,等待的过程,不要cpu,所以这里线程多,也会给cpu造成负担,cpu16核,整个32个线程,不犯毛病(不耗cpu,甚至cpu占用很低)———

实际上,一部分cpu密集,一部分Io密集,是我们工作中的常态,此时一个线程多少在cpu上执行,多少等待IO,说不好,更好的做法:自己去性能测试一下,找到性能和开销比较均衡的数值


六、💔 

多线程进阶开启:

常见的锁策略

如果工作中,真正要实现一把锁,需要理解锁策略

1.乐观锁VS悲观锁

乐观锁:预测,不太会出现锁冲突的情况

悲观锁:预测,这个场景非常容易锁冲突

2.重量级锁VS轻量级锁

重量级锁:加锁开销比较大,花的时间多,占有系统资源,一个悲观锁,很可能是重量级锁

轻量级锁:花的时间少,占有资源少,加锁的开销比较小的,很可能是乐观锁

悲观,乐观是加锁之前堆冲突概率的预测,决定工作的多少,重量,轻量,是加锁后,考虑实际的锁开销

3.自旋锁VS刮起等待锁

自旋锁是轻量级的一种典型实现,在用户态通过自旋的方式(while循环),实现类似加锁的操作(一直在疯狂的舔,这种锁会耗一定的cpu,但是是最快速度拿到锁的)

挂起等待锁:通过内核态,借助系统提供的锁机制,当出现锁冲突,会牵扯到内核对线程的调度,是冲突的线程出现挂起(阻塞等待)重量级锁的一种典型体现,发现锁被占用后,自己该干啥干啥,偶尔听到了消息,又去找这个锁,耗费cpu少,但无法第一时间拿到锁(小摆烂)

4.读写锁VS互斥锁

读写锁:把读操作,写操作分开了

假如两个线程 一个读加锁,另一个还是读加锁,那么两个不会有锁竞争(目的:就是把这种情况处理,这样多线程的效率会更高)

一个读,一个写,两个都是写都会有锁竞争,但是两个读没事,在开发中读操作会比写操作更加频繁

互斥锁:写了就不能读,读了就不可以写,

5.公平锁VS非公平锁

公平锁是遵循先来后到这个规则的

非公平锁相当于超市促销,都来抢位置,不遵守顺序

操作系统自带锁(pthread-mutex)是非公平锁,要实现公平锁,就需要一些额外的数据结构来支持(比如需要有办法记录每个线程的阻塞等待时间)

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

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

相关文章

Redis系列(一):深入了解Redis数据类型和底层数据结构

Redis有以下几种常用的数据类型&#xff1a; redis数据是如何组织的 为了实现从键到值的快速访问&#xff0c;Redis 使用了一个哈希表来保存所有键值对。 Redis全局哈希表&#xff08;Global Hash Table&#xff09;是指在Redis数据库内部用于存储所有键值对的主要数据结构。…

安卓13不再支持PPTP怎么办?新的连接解决方案分享

随着Android 13的发布&#xff0c;我们迎来了一个令人兴奋的新品时刻。然而&#xff0c;对于一些用户而言&#xff0c;这也意味着必须面对一个重要的问题&#xff1a;Android 13不再支持PPTP协议。如果你是一个习惯使用PPTP协议来连接换地址的用户&#xff0c;那么你可能需要重…

C++ 泛型编程:函数模板

文章目录 前言一、什么是泛型编程二、函数模板三、函数模板的使用四、多参数函数模板五&#xff0c;示例代码&#xff1a;总结 前言 当需要编写通用的代码以处理不同类型的数据时&#xff0c;C 中的函数模板是一个很有用的工具。函数模板允许我们编写一个通用的函数定义&#…

接口测试之Jmeter+Ant+Jenkins接口自动化测试平台

平台简介 一个完整的接口自动化测试平台需要支持接口的自动执行&#xff0c;自动生成测试报告&#xff0c;以及持续集成。Jmeter支持接口的测试&#xff0c;Ant支持自动构建&#xff0c;而Jenkins支持持续集成&#xff0c;所以三者组合在一起可以构成一个功能完善的接口自动化…

idea - 刷新 Git 分支数据 / 命令刷新 Git 分支数据

一、idea - 刷新 Git 分支数据 idea 找到 fetch 选项&#xff0c;重新获取分支数据 二、命令刷新 Git 分支数据 git fetch参考链接 1. 远程Gitlab新建的分支在IDEA里不显示

jxls导出问题

![请添加图片描述](https://img-blog.csdnimg.cn/bc74c4207818491c93b75e19b3333451.png 为什么最后导出的文件还是按原样导出啊&#xff0c;没有填充数据 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d4500b9a98c042f6b64a5d0650071303.png

ChatGPT等人工智能编写文章的内容今后将成为常态

BuzzFeed股价上涨200%可能标志着“转向人工智能”媒体趋势的开始。 周四&#xff0c;一份内部备忘录被华尔街日报透露BuzzFeed正计划使用ChatGPT聊天机器人-风格文本合成技术来自OpenAI&#xff0c;用于创建个性化盘问和将来可能的其他内容。消息传出后&#xff0c;BuzzFeed的…

文本三剑客之grep命令和awk命令 1.0 版本

grep awk 1.grep命令1.1 基本格式1.2 常用选项 2.awk命令2.1 awk工作原理2.2 awk命令格式2.3 awk常用内置变量 1.grep命令 1.1 基本格式 grep [选项]… 查找条件 目标文件1.2 常用选项 选项功能 -m [ x ]匹配x次 后停止,x为具体数字-v取反 -i忽略字符大小写 -n显示匹配的 …

Dynamic CRM开发 - 实体介绍

实体简介 在CRM中,实体(Entity)是数据的基本载体,也是构建业务逻辑网络的基础节点。 实体可以理解为数据库中的一张表(实体中的字段对应数据库表的字段),比如创建一个实体存储客户信息,创建一个实体存储产品信息,产品实体里可以创建一个查找类型的字段(类似表的外键)…

【三维编辑】Seal-3D:基于NeRF的交互式像素级编辑

文章目录 摘要一、引言二、方法2.1.基于nerf的编辑问题概述2.2.编辑指导生成2.3.即时预览的两阶段学生训练 三、实验四、代码总结 项目主页: https://windingwind.github.io/seal-3d/ 代码&#xff1a;https://github.com/windingwind/seal-3d/ 论文: https://arxiv.org/pdf/23…

阿里云轻量应用服务器_2核4G4M_2核2G3M_性能测评

阿里云轻量应用服务器2核2G3M带宽108元一年&#xff0c;系统盘为50GB高效云盘&#xff1b;轻量服务器2核4G4M带宽&#xff0c;60GB高效云盘297.98元12个月。目前轻量应用服务器只有2核2G和2核4G有活动&#xff0c;阿里云百科分享阿里云轻量应用服务器入口&#xff1a; 目录 阿…

【Qt高阶】老Qt都不一定清楚的“QObject线程亲和性”【2023.08.13】

老Qt都不一定清楚的“线程亲和性” 与题目无关 感觉自己还挺2&#xff0c;有粉丝点了那个契约者会给up发个鼓励的话&#xff0c;我还以为是人私信发的&#xff0c;都挨个感谢了&#xff0c;后来才意识到是系统自动发的&#x1f623;&#x1f623;&#x1f623;。 自上上期视频对…

Three.js阴影

目录 Three.js入门 Three.js光源 Three.js阴影 Three.js纹理贴图 使用灯光后&#xff0c;场景中就会产生阴影。物体的背面确实在黑暗中&#xff0c;这称为核心阴影&#xff08;core shadow&#xff09;。我们缺少的是落下的阴影&#xff08;drop shadow&#xff09;&#…

【数据结构】——栈、队列的相关习题

目录 题型一&#xff08;栈与队列的基本概念&#xff09;题型二&#xff08;栈与队列的综合&#xff09;题型三&#xff08;循环队列的判空与判满&#xff09;题型四&#xff08;循环链表表示队列&#xff09;题型五&#xff08;循环队列的存储&#xff09;题型六&#xff08;循…

一文揭秘饿了么跨端技术的演进、实践与落地

跨端技术背景与演进历程 跨端&#xff0c;究竟跨的是哪些端&#xff1f; 自 90 年的万维网出现&#xff0c;而后的三十多年&#xff0c;我们依次经历了 PC 时代、移动时代&#xff0c;以及现在的万物互联&#xff08;的 IoT &#xff09;时代&#xff0c;繁荣的背后&#xff…

【Apollo】Apollo-ros版本架构学习与源码分析

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Apollo-ros版本架构学习与源码分析。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&a…

解决GitHub的速度很慢的几种方式

1. GitHub 镜像访问 这里提供两个最常用的镜像地址&#xff1a; https://hub.njuu.cf/search https://www.gitclone.com/gogs/search/clonesearch 也就是说上面的镜像就是一个克隆版的 GitHub&#xff0c;你可以访问上面的镜像网站&#xff0c;网站的内容跟 GitHub 是完整同步…

期权定价模型系列【4】—期权组合的Delta-Gamma-Vega中性

期权组合的Delta-Gamma-Vega中性 期权组合构建时往往会进行delta中性对冲&#xff0c;在进行中性对冲后&#xff0c;期权组合的delta敞口为0&#xff0c;此时期权组合仍然存在gamma与vega敞口。因此研究期权组合的delta-gamma-vega敞口中性是有必要的。 本文旨在对delta-gamma-…

关于新手学习STM32开发应该如何入门?

对于新手来说&#xff0c;学习STM32开发可能会感到困惑&#xff0c;尤其是在拿到开发板后该如何入门。在这里有嵌入式学习路线&#xff0c;毕设&#xff0c;各种项目&#xff0c;需要留个6。以下是部分内容概述&#xff1a;硬件介绍&#xff1a;了解STM32开发板的基本硬件组成和…

如何让你的图片服务也有类似OSS的图片处理功能

原文链接 前言 有自己机房的公司一般都有一套存储系统用于存储公司的图片、视频、音频、文件等数据&#xff0c;常见的存储系统有以NAS、FASTDFS为代表的传统文件存储&#xff0c;和以Minio为代表的对象存储系统&#xff0c;随着云服务的兴起很多公司逐渐将数据迁移到以阿里云…