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

目录

  • 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方法。
然后两个线程会交换彼此的数据,并继续执行。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c++写入数据到文件中

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

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

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

【教3妹学编程-算法题】一年中的第几天

3妹&#xff1a;“太阳当空照&#xff0c;花儿对我笑&#xff0c;小鸟说早早早&#xff0c;你为什么背上炸药包” 2哥 :3妹&#xff0c;什么事呀这么开森。 3妹&#xff1a;2哥你看今天的天气多好啊&#xff0c;经过了一周多的寒潮&#xff0c;天气总算暖和些了。 2哥&#xff…

VUE——IDEA 启动前端工程VS文件启动前端工程

IDEA 启动前端 目录 前言一、打开控制台二、输入npm install三、依赖下载完之后&#xff0c;输入npm run dev&#xff0c;运行前端项目1、IDEA启动前端工程2、文件目录启动前端工程 四、点击http://localhost:8080后续敬请期待 前言 启动已有的vue前端项目 一、打开控制台 选…

服务器硬件及RAID配置实战

目录 1、RAID的概念 2、RAID的实现方式 3、标准的RAID 3.1 RAID 0 3.2 RAID 1 3.3 RAID 5 3.4 RAID 10 4、建立硬件 RAID的过程步骤 1、进入RAID 1.1 重启服务器 1.2 进入RAID界面 1.3 在RAID界面切换目录 2、创建RAID 2.1 移动到RAID卡 2.2 按F2&#xff0c;选择…

NullByte

信息收集 # nmap -sn 192.168.1.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2023-12-29 09:23 CST Nmap scan report for 192.168.1.1 Host is up (0.00038s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for …

Rust学习笔记006:代码组织

Crate 在Rust中&#xff0c;“crate” 是指 Rust 的代码单元&#xff0c;它可以包含一个或多个模块&#xff08;modules&#xff09;。Rust 的 crate 分类主要有两个方面&#xff1a;库&#xff08;Library Crates&#xff09;和二进制&#xff08;Binary Crates&#xff09;。…

UE4运用C++和框架开发坦克大战教程笔记(十三)(第40~42集)

UE4运用C和框架开发坦克大战教程笔记&#xff08;十三&#xff09;&#xff08;第40~42集&#xff09; 40. 多按键绑定41. 自动生成对象42. 资源模块数据结构测试自动生成对象按资源类型生成对象 40. 多按键绑定 上节课实现了按键绑定系统的 4 种基础绑定&#xff0c;这节课来…

【大数据面试知识点】Spark的DAGScheduler

Spark数据本地化是在哪个阶段计算首选位置的&#xff1f; 先看一下DAGScheduler的注释&#xff0c;可以看到DAGScheduler除了Stage和Task的划分外&#xff0c;还做了缓存的跟踪和首选运行位置的计算。 DAGScheduler注释&#xff1a; The high-level scheduling layer that i…

畅捷通的 Serverless 探索实践之路

作者&#xff1a;计缘&#xff0c;阿里云云原生架构师 畅捷通介绍 畅捷通是中国领先的小微企业财税及业务云服务提供商&#xff0c;成立于 2010 年。畅捷通在 2021 年中国小微企业云财税市场份额排名第一&#xff0c;在产品前瞻性及行业全覆盖方面领跑市场&#xff0c;位居中…

C:Huffman编码a

【问题描述】 给定一组字符的Huffman编码表&#xff08;从标准输入读取&#xff09;&#xff0c;以及一个用该编码表进行编码的Huffman编码文件&#xff08;存在当前目录下的in.txt中&#xff09;&#xff0c;编写程序实现对Huffman编码文件的解码&#xff0c;并按照后序遍历序…

【UE 截图】 自定义截图路径 文件名

目录 0 引言1 实践 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;UE虚幻引擎专栏&#x1f4a5; 标题&#xff1a;【UE 截图】 自定义截图路径 文件名❣️ 寄语&#xff1a;书到用时方恨少&#xff0c;事非经过不知难&#xff01;&#x1f388; 最…

zlib.decompressFile报错 【Bug已解决-鸿蒙开发】

文章目录 项目场景:问题描述原因分析:解决方案:方案1方案2此Bug解决方案总结寄语项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了zlib.decompressFile报错 的问题。 问题: zlib.decompressFile报错,怎么解…

基于ssm的房屋租赁管理系统

功能介绍 房源信息模块&#xff1a; 房源信息展示、房源信息更新、房源信息增加、房源信息删除 账户管理模块&#xff1a; 账户登录、账户绑定、账户管理 租金结算模块&#xff1a; 每月租金信息、租金交付功能、月租金收入总额统计 房屋租赁合同管理模块&#xff1a; 房屋租赁…

【C语言】函数

函数是什么&#xff1f; “函数”是我们早些年在学习数学的过程中常见的概念&#xff0c;简单回顾一下&#xff1a;比如下图中&#xff0c;你给函数 f(x)2*x3 一个具体的x,这个函数通过一系列的计算来返回给你一个结果(图示如下)。 这就是数学中函数的基本过程和作用。但是你…

1.4 FMEA概述

FMEA适用场景 FMEA在三种基本情形下使用&#xff0c;每种情形都有不同的范围或重点。 情形1&#xff1a;新设计、新技术或新过程 FMEA的范围包括完整的设计、技术或过程。 情形2&#xff1a;现有设计或过程的新应用 FMEA的范围包含新环境、新场地、新应用或使用概况&#…

Servlet见解3

13 Cookie和Session http协议是一个无状态的协议&#xff0c;你每一个跳转到下一个页面的时候都是需要先登录才能使用&#xff0c;这样就很麻烦比如淘宝&#xff0c;没有cookie和session的话&#xff0c;用户在首页已经登录上去了&#xff0c;但是需要再次登录才能选择商品&am…

买对好车省钱又防坑,高性价比的买车攻略

一、教程描述 正所谓隔行如隔山&#xff0c;买车这件事情并不简单&#xff0c;买车的内幕还是有不少的&#xff0c;本套教程讲述买车攻略&#xff0c;非常适合准备买车的朋友&#xff0c;可以帮助大家买车少入坑&#xff0c;高性价比买到自己心仪的车。本套买车教程&#xff0…

Android 13 动态启用或禁用IPV6

介绍 客户想要通过APK来控制IPV6的启用和禁用&#xff0c;这里我们通过广播的方式来让客户控制IPV6。 效果展示 adb shell ifconfig 这里我们用debug软件&#xff0c;将下面节点置为1 如图ipv6已被禁用了 echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6 修改 接下来…

十大排序总结之——冒泡排序、插入排序

同样&#xff0c;这两几乎也是被淘汰了的算法&#xff0c;尽管它们是稳定的&#xff0c;但是时间复杂度没人喜欢&#xff0c;了解一下就好&#xff0c;没啥好说的&#xff0c;注意最后一句话就行了 一&#xff0c;冒泡排序 1. 算法步骤 共n-1趟&#xff0c;谁两敢冒泡就换了…