Java多线程之线程池,volatile,悲观锁,乐观锁,并发工具类

news2024/11/29 9:34:04

目录

  • 1.线程池核心原理
    • 1.创建线程池
    • 2.任务拒绝策略
    • 3.自定义线程池
  • 2.线程池的大小
    • 1.最大并行数
    • 2.影响线程池大小的因素
  • 3.多线程常见考点(volatile,悲观锁,乐观锁)
  • 4.并发工具类

1.线程池核心原理

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

1.创建线程池

Executors:线程池工具类通过调用方法返回不同类型的线程池对象。

在这里插入图片描述
创建一个上限为3的线程池:

public class Main{
    public static void main(String[] args) {
        //获取线程池对象
        ExecutorService pools = Executors.newFixedThreadPool(3);
        //提交任务
        pools.submit(new MyRunnable());
        pools.submit(new MyRunnable());
        pools.submit(new MyRunnable());
        //销毁线程池
        pools.shutdown();
    }
}

2.任务拒绝策略

自定义线程池执行优先级分贝为:核心线程,临时线程,阻塞队列。

在这里插入图片描述

3.自定义线程池

public class Main{
    public static void main(String[] args) {
        //创建自定义线程池
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3,//核心线程数量,不能小于0
                6,//最大线程数,要大于核心线程数
                60,//空闲线程最大存活时间
                TimeUnit.SECONDS,//时间单位
                new ArrayBlockingQueue<>(3),//任务队列
                Executors.defaultThreadFactory(),//创建线程工厂
                new ThreadPoolExecutor.AbortPolicy()//任务拒绝策略
        );
    }
}

2.线程池的大小

1.最大并行数

最大并行数指的是在线程池中同时执行的最大线程数量。
当线程池中的活动线程数量达到最大并行数时,新的任务会进入等待队列,直到有可用的线程资源。
通过控制最大并行数,可以有效地管理线程池的负载,避免过多的并发线程导致系统资源耗尽。

查看电脑的最大线程数量

        //利用java虚拟机查看可用处理器的数目
        System.out.println(Runtime.getRuntime().availableProcessors());

2.影响线程池大小的因素

根据项目的运算需求决定:
CPU密集型运算:
线程池大小 = 最大并行数 + 1 线程池大小=最大并行数+1 线程池大小=最大并行数+1
I/O密集型运算:
最大并行数 ∗ 期望 C P U 利用率 ∗ 总时间( C P U 计算时间 + 等待时间) C P U 计算时间 最大并行数*期望CPU利用率*\frac{总时间(CPU计算时间+等待时间)}{CPU计算时间} 最大并行数期望CPU利用率CPU计算时间总时间(CPU计算时间+等待时间)

3.多线程常见考点(volatile,悲观锁,乐观锁)

volatile关键字
volatile是一个Java关键字,用于修饰变量。
当一个变量被声明为volatile时,意味着这个变量的值可能会被多个线程同时修改。
volatile关键字的作用是告诉编译器和JVM,对于这个变量的读写操作不能进行重排序,且每次读取该变量时都必须从内存中读取最新的值,而不是使用缓存。
这样可以保证多个线程能够正确地读取到最新的值,从而避免了数据不一致的问题。

悲观锁
悲观锁是一种线程同步机制,用于确保在多线程环境下对共享资源的安全访问。
悲观锁的基本思想是假设在未来的某个时间点会有其他线程来访问共享资源,因此通过阻塞和限制其他线程的访问以确保数据的一致性和完整性
在悲观锁的实现中,当一个线程访问共享资源时,会将该资源加锁,以阻塞其他线程对该资源的访问。
只有当当前线程完成对资源的操作后,其他线程才能获取到锁,然后才能访问资源。
悲观锁的特点是,在多线程环境下会频繁地加锁和释放锁,这会导致线程切换的开销增加。
因此,悲观锁适用于对共享资源的访问频率较低的情况,以减少线程之间的竞争。
常见的悲观锁实现包括互斥锁(Mutex)和读写锁(ReadWriteLock)。
互斥锁可以确保同一时间只有一个线程能够访问共享资源,而读写锁在读操作时允许多个线程同时访问共享资源,在写操作时只允许一个线程访问

乐观锁
乐观锁是一种并发控制机制,它假设多个线程之间很少会发生冲突,因此不会进行显式的加锁操作,而是通过一种乐观的方式进行并发访问。

在乐观锁机制中,线程在读取数据时,不会对数据进行加锁,而是先读取数据的版本号,然后在对数据进行修改时,再次检查版本号是否发生变化。
如果版本号没有变化,说明其他线程没有修改过数据,当前线程可以进行修改,并更新版本号;如果版本号发生了变化,说明其他线程已经修改过数据,当前线程需要重新读取数据,然后再次尝试修改。
乐观锁相对于悲观锁来说,减少了对数据的加锁和解锁操作,因此在高并发场景下,乐观锁的性能通常比悲观锁更好
但是,由于乐观锁需要进行额外的版本号检查和数据重读操作,因此如果冲突较多,可能会导致性能下降。

4.并发工具类

ConcurrentHashMap
ConcurrentHashMap是Java中的一个线程安全的哈希表,它用于在多线程环境下进行并发访问的操作。
它提供了一种高效的方式来存储和操作键值对
ConcurrentHashMap的主要作用是在多线程环境中提供安全的并发访问
它通过使用分段锁(Segment)来提高并发情况下的性能。
每个Segment可以理解为一个独立的哈希表,不同的线程可以同时访问不同的Segment,从而减小了锁的粒度,提高了并发性能。

CountDownLatch
CountDownLatch是一个并发辅助类,它可以使一个或多个线程等待其他线程完成操作后再继续执行
在Java多线程中,CountDownLatch的作用是控制线程的执行顺序
当一个或多个线程需要等待其他线程完成某些操作后再继续执行时,可以使用CountDownLatch来实现。

CyclicBarrier
CyclicBarrier(循环屏障)是Java多线程中的一个同步工具类,用于控制线程的执行顺序和并发同步。
它可以让一组线程在某个点上等待,直到所有线程都达到这个点,然后执行后续操作

Semaphore
在Java多线程中,Semaphore(信号量)是一种用于控制同时访问特定资源(如线程数)的机制。
它可以用来限制同一时间内可以访问某个资源的线程数量

ExChanger
Exchanger是Java多线程中的一个工具类,用于线程之间的数据交换
它提供了一个同步点,在这个同步点上,两个线程可以交换彼此的数据。
具体来说,Exchanger有一个exchange方法,当一个线程调用exchange方法时,它会被阻塞,直到另一个线程也调用了exchange方法。
然后两个线程会交换彼此的数据,并继续执行。

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

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

相关文章

印象笔记01:初识印象笔记

印象笔记01&#xff1a;初识印象笔记 印象笔记是一个历史比较久的笔记软件&#xff0c;近几年营销渠道不断完善&#xff0c;软件生态也日渐健全。个人因为很早接触印象笔记&#xff0c;从有道云笔记转粉到印象笔记了&#xff08;2017 年&#xff09;。而且在前几年一下子开了十…

图像分割实战-系列教程3:unet医学细胞分割实战1(医学数据集、图像分割、语义分割、unet网络、代码逐行解读)

&#x1f341;&#x1f341;&#x1f341;图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 上篇内容&#xff1a; Unet系列算法 下篇内容&#xff1a; unet医学细胞分割实战2 1、医学细胞数据…

vite+Vue3学习笔记(3)——界面设计

1 Element-plus 这是一个基于Vue3的组件库&#xff0c;能够快速构建界面样式。 官网链接&#xff1a; https://element-plus.gitee.io/zh-CN/guide/design.html 1.1 基础组件 1.1.1 安装 项目中的终端输入&#xff1a; npm install --save element-plus 1.1.2 引用 1.1.2.1…

Spring Boot日志:从Logger到@Slf4j的探秘

写在前面 Hello大家好&#xff0c;今日是2024年的第一天&#xff0c;祝大家元旦快乐&#x1f389; 2024第一篇文章从SpringBoot日志开始 文章目录 一、前言二、日志有什么用&#xff1f;三、日志怎么用&#xff1f;四、自定义日志打印&#x1f4ac; 常见日志框架说明4.1 在程序…

打印菱形和金字塔类型(总结)

首先&#xff0c;在之前的学习中&#xff0c;我们了解了菱形的打印&#xff0c;今天我们来对金字塔和菱形这类打印图形的问题&#xff0c;我们来做一个总结。 这个总结的来源是这今天做了一道题 这道题的答案如下 这个题做起来并不难&#xff0c;拓展到这类问题中&#xff0c;…

Java智慧工地管理平台系统源码带APP端源码

智慧工地将“互联网”的理念和技术引入建筑工地&#xff0c;从施工现场源头抓起&#xff0c;最大程度地收集人员、安全、环境、材料等关键业务数据&#xff0c;依托物联网、互联网&#xff0c;建立云端大数据管理平台&#xff0c;形成“端云大数据”的业务体系和新的管理模式&a…

PTA——计算火车运行时间

本题要求根据火车的出发时间和达到时间&#xff0c;编写程序计算整个旅途所用的时间。 输入格式&#xff1a; 输入在一行中给出2个4位正整数&#xff0c;其间以空格分隔&#xff0c;分别表示火车的出发时间和到达时间。每个时间的格式为2位小时数&#xff08;00-23&#xff0…

JavaScript:BOM操作

JavaScript&#xff1a;BOM操作 BOM与JavaScript的关系window对象window对象的常用属性方法定时器间歇函数延时函数 JavaScript执行机制同步异步事件循环 location对象navigator对象histroy对象浏览器的本地存储localStoragesessionStorage 复杂数据类型的存储JSON字符串 BOM与…

浅谈Verilog代码的执行顺序

一、组合逻辑和时序逻辑 数字电路可以分成两大类&#xff0c;一类叫组合逻辑电路&#xff0c;另一类叫做时序逻辑电路。 组合逻辑电路&#xff1a;由门电路组成&#xff0c;其某一时刻的输出状态只与该时刻的输入状态有关&#xff0c;而与电路原来的状态无关&#xff0c;并没有…

基于Java SSM框架实现健康管理系统项目【项目源码】

基于java的SSM框架实现健康管理系统演示 JSP技术 JSP是一种跨平台的网页技术&#xff0c;最终实现网页的动态效果&#xff0c;与ASP技术类似&#xff0c;都是在HTML中混合一些程序的相关代码&#xff0c;运用语言引擎来执行代码&#xff0c;JSP能够实现与管理员的交互&#xf…

AI模型私人订制

使用AI可以把你的脸换成明星的脸&#xff0c;可以用于直播、录播。 AI换脸1 也可以把视频中明星的脸换成你的脸 AI换脸2 之所以能够替换成功&#xff0c;是因为我们有一个AI人物模型&#xff0c;AI驱动这个模型就可以在录制视频的时候替换指定人物的脸。AI模型从哪里来&…

c++写入数据到文件中

假设你想编写一个C程序&#xff1a;当你在调试控制台输入一些数据时&#xff0c;系统会自动存入到指定的文件中&#xff0c;该如何操作呢&#xff1f; 具体操作代码如下&#xff1a; #include<iostream> #include<string> #include<fstream> using namespa…

Elasticsearch:在不停机的情况下优化 Elasticsearch Reindex

实现零停机、高效率和成功迁移更新的指南。更多阅读&#xff1a;Elasticsearch&#xff1a;如何轻松安全地对实时 Elasticsearch 索引 reindex 你的数据。 在使用 Elasticsearch 的时候&#xff0c;总会有需要修改索引映射的时候&#xff0c;遇到这种情况&#xff0c;我们只能做…

作业--day39

定义一个Person类&#xff0c;私有成员int age&#xff0c;string &name&#xff0c;定义一个Stu类&#xff0c;包含私有成员double *score&#xff0c;写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数&#xff0c;完成对Person的运算符重载(算术运算符、条件运算…

十八、任务通知

1、前言 (1)所谓“任务通知”&#xff0c;可以反过来读"通知任务"。我们使用队列、信号量、事件组等等方法时&#xff0c;并不知道对方是谁。使用任务通知时&#xff0c;可以明确指定&#xff1a;通知哪个任务。 (2)使用队列、信号量、事件组时&#xff0c;我们都需…

C++初阶——权限与继承

目录 一、C权限方面的问题 1.访问权限 2.继承机制 二、Cconst引用 const引用有以下几个特点 临时对象引用 常量引用成员变量 二、c引用空间相关问题 三.auto 一、C权限方面的问题 【C入门】访问权限管控和继承机制详解_权限继承功能-CSDN博客文章浏览阅读840次。(2)但…

C#中string.ToUpper()和string.ToLower()的用法

目录 一、关于ToUpper()和ToLower() 1.ToUpper() 2.ToLower() 3.小结 二、实例 三、生成效果 一、关于ToUpper()和ToLower() 1.ToUpper() 使用字符串对象的ToUpper方法可以将字符串中的字母全部转换为大写。 string P_str_book "mingribook".ToUpper()…

简单Diff算法

简单Diff算法 渲染器的核心 Diff算法 解决的问题 比较新旧虚拟节点的子节点&#xff0c;实现最小化更新。 虚拟节点key属性的作用 就像虚拟节点的“身份证号”&#xff0c;在更新时&#xff0c;渲染器会通过key属性找到可复用的节点&#xff0c;然后尽可能地通过DOM移动操…

Spring Boot Admin健康检查引起的Spring Boot服务假死

问题现象 最近在spring boot项目中引入了 spring-boot-starter-actuator 后&#xff0c;测试环境开始出现服务假死的现象&#xff0c; 且这个问题十分怪异&#xff0c;只在多个微服务中的简称A的这个服务中出现&#xff0c;其他服务都没有出现这个问题&#xff0c; 之所以说…

Proxmox Backup Server(PBS)从2.X升级到PBS3

作者&#xff1a;田逸&#xff08;formyz&#xff09; 2023年11月31日&#xff0c;Proxmox 官方正式发布Proxmox Backup Server 3.1版本。现在我负责管理的Proxmox Backup Server&#xff08;以下简称PBS&#xff09;版本号为2.3&#xff0c;打算将部分PBS升级到PBS 3.1&#x…