JAVA基础进阶(十一)

一、创建线程的三种方式

Java语言中是用Thread类来表示线程,线程的创建和开启都是通过Thread类来实现的

继承Thread类重写run方法。

调用线程对象的start()方法启动线程(启动后还是执行run方法的),而不是调用创建的子类对象的run()方法。

可以使用匿名内部类创建Runnable接口的线程

具体这三种线程的创建可以看idea中的代码,已经都敲过了

二、3种创建线程方式的对比

三、线程Thread类的常用API

四、线程的安全问题

多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题(对共享资源进行增删改操作)。

五、线程池的创建、使用、参数

5.1线程池的作用

线程池的作用:线程池就是一个可以复用线程的技术

例如:不使用线程池的情况下,10个请求我就要创建10个线程,并且使用完后还要销毁这些线程。使用线程池后,我只创建3个线程,再这3个线程处理完当前线程后,就会处理任务队列中剩下的线程,并且核心线程是不会被销毁的,会一直存在。(这里3个线程是随便写的,不是具体算出来的)。

线程过多会占用CPU、内存等资源,所以使用线程池后,会缓解这些现象的发生。

5.2 线程池的7个参数

5.3创建线程池的方式

2、使用ThreadPoolExecutor创建线程池(阿里规范中只能使用这个)

ArrayBlockingQueue<>(5):任务队列数量为5

LinkedBlockingQueue<>():任务队列数量无穷,可以存放无数个任务。

2、使用Executors工具类创建线程池。

5.4 线程池的执行流程

语言描述: 某某公司分部(threadFactory)为客户办理业务,一共有4个柜员(maximumPoolSize),不忙的时段就分配2个柜员(corePoolSize)办理业务,剩余2人休息。摆了4个椅子(workQueue),供客户进行等待。并且这个公司给员工定了个规定,就是当工作区的柜员都在工作,并且等待区的座位都做满时,那么处于休息区的柜员要出来帮忙。直到所有柜员都在工作,等待区也坐满了。那为了我们公司员工身体的考虑,暂时拒绝任何人来办理业务(handler),如果有某个员工空闲下来并且超过了10(keepAliveTime)分钟(unit),那就可以回到休息区休息,但是必须保证有2个柜员在工作区。

5.5 线程池的拒绝策略

5.5 线程池处理Runnable任务

线程池处理Runnable任务是使用execute方法。ThreadPoolExecutor中的execute方法:

  1. 线程池会创建线程并调用线程中的run方法
  2. execute方法中需要的参数是Runnable接口的实现类
  3. 这种方法和submit方法最大的区别是没有返回值

创建Runnable接口的实现类MyRunnable,具体的代码如下:

其中Thread.sleep(Integer.MAX_VALUE),是为了让线程一直执行,这样就不会执行完之后去执行后面的线程。

创建一个线程池,核心线程数为3,最大线程数为5,队列中可存放的线程数量为2。

使用execute方法创建3个线程任务:

此时会创建3个线程。

使用execute方法创建5个线程任务:

核心线程数为3,所以还是创建3个线程。剩下的2个线程任务放入任务队列中。

使用execute方法创建7个线程任务:

核心线程数为3,所以还是创建3个线程。2个线程任务放入任务队列中。剩下的2个线程任务由创建的2个临时线程执行。

使用execute方法创建8个线程任务:

核心线程数为3,所以还是创建3个线程。2个线程任务放入任务队列中。剩下的2个线程任务由创建的2个临时线程执行。最后的一个线程任务会直接触发拒绝策略。

上面演示execute方法创建线程的过程正好验证了5.4中线程池的执行流程。

5.6 线程池处理Callable任务

线程池处理Callable任务是使用submit方法。ThreadPoolExecutor中的submit方法:

  1. 返回值类型为Future
  2. 通过get方法获得具体的返回值

六、进程和线程的关系

进程是程序的一个执行实例,是正在执行的程序一个进程可以包括多个线程。下面展示的就是多个进程,每个进程里面又包含多个线程。例如开启一个百度网盘,百度网盘这个进程中就可以包括下载线程和传输线程等。

七、物理CPU、核心数、逻辑处理器之间的关系

首先,需要知道的是:

1、物理CPU数就是主板上实际插入的CPU数量。

2、CPU的核心数是指物理上,也就是硬件上存在着几个核心。比如,双核就是包括2个相对独立的CPU核心单元组,四核就包含4个相对独立的CPU核心单元组。

3、总核数 = 物理CPU个数 × 每颗物理CPU的核数

4、总逻辑CPU数(总逻辑处理器数) = 物理CPU个数 × 每颗物理CPU的核数 × 超线程数

7.1、查看物理CPU的个数

cmd命令中输入“systeminfo”,以下信息表示物理CPU1

7.2、查看CPU核心数、线程数

cmd命令中输入“wmic”,然后在出现的新窗口中输入“cpu get *”

NumberOfCores:表示CPU核心数

NumberOfLogicalProcessors:表示CPU线程数

这里的CPU线程数和任务管理器中CPU的逻辑处理器是一样的,表示在某个瞬间CPU能同时并行处理的任务数。

对应任务管理器中的CPU的内核数和逻辑处理器

逻辑处理器表示CPU能同时处理线程的个数,所以CPU能同时处理20个线程。

上面的结果表明CPU是14核20线程的,说明CPU包含14个相对独立的CPU核心单元组,能在某一时刻同时处理20个线程。

为什么是20个线程而不是28个线程呢?

i5 13600K采用的是混合架构,大小核设计,由6个性能核+8个能效核混合架构组成导致的,其中性能核支持超线程,而能效核转不支持超线程。性能核通过超线程技术,1个核心可以对应两个线程,也就是说它可以同时运行两个线程,所以6个性能核对应12个线程,最终12+8得出来20个线程,而不是28个线程。

参考地址:

Windows下查看电脑的CPU个数,核心数,线程数_如何查看电脑核心数-CSDN博客

https://www.cnblogs.com/fetty/p/8580583.html

八、 并发、并行的概念

并发:CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们感觉这些线程在同时执行,这就是并发。

这些线程并不是同时执行,而是由于CPU的切换速度很快,给人感觉像是在同时执行。例如之前介绍的CPU是14核20线程,

这个CPU最多能同时执行20个线程,CPU就会轮询的执行例如前20个线程,再执行后面的20个线程,再执行前面20个线程,给人感觉这40个线程像是在同一时刻执行。

并行:在同一个时刻上,同时有多个线程在被CPU处理并执行。这里指的是实际被同时执行的线程,例如之前介绍的CPU是14核20线程,这个CPU最多能同时执行20个线程,所以在同一时刻,最多同时有20个线程被CPU处理并执行。

总结:

并发:CPU分时轮询的执行线程。

并行:同一个时刻同时在执行

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

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

相关文章

MSUSB30模拟开关可Pin to Pin兼容FSUSB30/SGM7222

MSUSB30/MSUSB30N 是一款高速、低功耗双刀双掷 USB 模拟开关芯片&#xff0c;其工作电压范围是1.8V 至5.5V。可Pin to Pin兼容FSUSB30/SGM7222。其具有低码间偏移、高通道噪声隔离度、宽带宽的特性。 MSUSB30/MSUSB30N 主要应用范围包括&#xff1a;具有 USB2.0 接口的手持设备…

Linux “grep“ 命令

1. 目标 本文主要介绍 Linux "grep" 命令&#xff1a;用于查找文件里符合条件的字符串或正则表达式。 2. grep 命令 "grep" 命令的基本语法是&#xff1a; grep [options] pattern [files]pattern - 表示要查找的字符串或正则表达式。 files - 表示要查…

shared_ptr子类指针转换成父类指针

假设有如下应用场景: class Base { public:void addChild(std::shared_ptr<Base>& child){...} }class Derived : public Base {}int main() {Base a;std::shared_ptr<Derived> b std::make_shared<Derived>();a.addChild(b); // Error } 该代码中声…

Response(Http协议连载)

Response对象 功能&#xff1a; 设置响应消息 设置响应行 格式&#xff1a;HTTP/1.1 200 ok 设置状态码&#xff1a;setStatus(int sc) 设置响应头 设置头&#xff1a;setHeader(String name,String value); 设置响应体 使用步骤&#xff1a; 获取输出流 字符输出流&#xff…

[UGUI]实现从一个道具栏拖拽一个UI道具到另一个道具栏

在Unity游戏开发中&#xff0c;实现UI道具的拖拽功能是一项常见的需求。本文将详细介绍如何使用Unity的UGUI系统和事件系统&#xff0c;实现从一个道具栏拖拽一个UI道具到另一个道具栏的功能。 一、准备工作 首先&#xff0c;你需要在Unity中创建两个道具栏和一些UI道具。道具…

事件机制?

事件流&#xff1a; 描述的页面接收事件的顺序。先进行事件捕获 到达目标元素 在进行事件冒泡 分为事件捕获和事件冒泡 事件冒泡&#xff1a;从具体元素从内向外依次触发事件 从下面这个小案例可以清楚了解什么是事件冒泡 <!DOCTYPE html> <html lang"en"…

C++ -- 每日选择题 -- Day2

第一题 1. 下面代码中sizeof(A)结果为&#xff08;&#xff09; #pragma pack(2) class A {int i;union U{char str[13];int i;}u;void func() {};typedef char* cp;enum{red,green,blue}color; }; A&#xff1a;20 B&#xff1a;21 C&#xff1a;22 D&#xff1a;24 答案及解析…

leecode 回文数

给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#xff0c;而…

Linux 挂载文件系统为可读写 mount -uw / 和 mount -o remount,rw /

Linux 挂载文件系统为可读写 mount -uw / 和 mount -o remount,rw / 在挂载文件系统为可读写时&#xff0c;我发现一个问题&#xff0c;有时用mount -uw /就可以把文件系统挂载成可写的状态。但有时就会发生 “read-only file system” 的错误&#xff0c;这时我用mount -o re…

智能优化算法应用:基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.纵横交叉算法4.实验参数设定5.算法结果6.参考…

【字符串探秘:手工雕刻的String类模拟实现大揭秘】

【本节目标】 1. string类的模拟实现 2.C基本类型互转string类型 3.编码表 &#xff1a;值 --- 符号对应的表 4.扩展阅读 1. string类的模拟实现 1.1 经典的string类问题 上面已经对string类进行了简单的介绍&#xff0c;大家只要能够正常使用即可。在面试中&#xff0c;…

1.网络编程基础知识 - 基础概念、TCP网络通信、UDP网络通信

网络编程 文章目录 网络编程一、概念1.1 网络1.2 IP地址1.2.1 IPv4 介绍1.2.2 IPv6 介绍1.2.3 查看IP地址 1.3 域名和端口1.4 网络协议1.5 TCP与UDP1.6 InetAddress类1.7 Socket 二、TCP网络通信编程2.1 介绍2.2 案例2.2.1 字节流编程案例12.2.2 字节流编程案例22.2.3 字符流编…

【UGUI】Unity教程:实现物品的拖拽功能

大家好&#xff0c;今天&#xff0c;我们将一起学习如何在Unity中实现物品的拖拽功能。这是一个非常实用的技能&#xff0c;无论你是在制作RPG游戏的背包系统&#xff0c;还是在制作策略游戏的建筑放置功能&#xff0c;都会用到这个技能。那么&#xff0c;让我们开始吧&#xf…

5. 文件属性和目录

5. 文件属性和目录 1. Linux 系统的文件类型1.1 普通文件1.2 目录文件1.3 字符设备文件和块设备文件1.4 符号链接文件1.5 管道文件1.6 套接字文件 2. stat 系统调用2.1 struct stat 结构体2.2 st_mode 变量2.3 struct timespec 结构体 3. fstat 和 lstat 函数3.1 fstat 函数3.2…

python中的序列

文章目录 序列类型标准类型运算符标准类型运算符序列类型运算符字符串 序列类型 字符串 列表 元组 由元组构成的列表 标准类型运算符 &#xff08;1&#xff09;按字符串大小比较 标准类型运算符 序列类型运算符 序列类型转换内建函数 注&#xff1a; &#xff08;1&#xff…

深入理解MySQL索引底层数据结构与算法

索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构 索引的数据结构 二叉树红黑数Hash表B-Tree MySQL索引底层为啥不用二叉树 如图&#xff0c;对单边增长的数据&#xff0c;索引效率没有什么提升 MySQL索引底层为啥不用红黑数 红黑数&#xff1a;二叉平衡树 随…

并发与数据一致性:事务的保障

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等&#xff0c;您的关注将是我的更新动力&#xff01; 并发 并发是计算机系统中同时执行多个独立任务的能力。通过共享资源和并发执行&#xff0c;系统可以提高性能和效率。然而&…

【C 语言经典100例】C 练习实例29

题目&#xff1a;给一个不多于5位的正整数&#xff0c;要求&#xff1a;一、求它是几位数&#xff0c;二、逆序打印出各位数字。 程序分析&#xff1a;学会分解出每一位数&#xff0c;如下解释。 #include <stdio.h>int main( ) {long a,b,c,d,e,x;printf("请输入…

silero-vad 官方新增了java 的demo

原来参考android GitHub - gkonovalov/android-vad: Android Voice Activity Detection (VAD) library. Supports WebRTC VAD GMM, Silero VAD DNN, Yamnet VAD DNN models.的kt改写java demo 可费劲了 上个月 https://github.com/snakers4/silero-vad/tree/master/examples…

MSSQL注入的入门讲解及示例

MSSQL注入是一种常见的网络攻击手段&#xff0c;主要是通过在输入框中插入恶意的SQL代码&#xff0c;使得MSSQL注入是一种常见的网络攻击手段&#xff0c;主要是通过在输入框中插入恶意的SQL代码&#xff0c;使得原本的SQL查询语句被篡改&#xff0c;从而达到攻击者的目的。下面…