当前位置: 首页 > news >正文

并发编程-Day2

并发编程

1.共享模型-内存

共享变量在多线程间的<可见性>问题与多条指令执行时的<有序性>问题

1.1Java内存模型

JMM它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存CPU指令优化等.

JMM体现在:

  • 原子性-保证指令不会受到线程上下文切换的影响
  • 可见性-保证指令不会受cpu缓存的影响
  • 有序性-保证指令不会受cpu指令并行优化的影响

1.2可见性

问题:通过变量控制while程序不能够停下来

@Slf4j
public class KeJianXingThreadD2 {static boolean flag = true;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (flag) {}});thread.start();Thread.sleep(3);log.debug("停止thread");flag = false;}
}

分析问题:

  • thread从内存读取了flag的值到工作内存中
  • thread线程频繁从主内存中读取flag的值,JIT编译器会将flag的值缓存到自己的工作内存中,减少对主内存中flaga的访问,提高效率
  • 3秒之后,main线程修改了flag的值,并同步到主内存中,而thread线程一直在读取自己的工作内存的值,一直是旧值,所以线程不会停下来

解决方案:

volatile(关键字)

可以修饰成员变量和静态成员变量,可以避免线程从自己的工作缓存中查找变量,必须到主内存获取它的值,线程操作volatile变量都是直接操作主

public class KeJianXingThreadD2 {volatile static boolean flag = true;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (flag) {}});thread.start();Thread.sleep(3);log.debug("停止thread");flag = false;}
}

只能保证可见性 不能保证原子性

1.3有序性

程序执行的顺序按照代码的先后执顺序执行.

编译器和处理器为了提高执行的效率性能,会对执行进行重排序,指令重排序对单线程应用没有影响,但是在多线程环境下可能出现问题.<重排序的代码没有执行完>

解决:volatile关键字解决

1.4volatile原理

  • 读屏障
  • 写屏障

2.共享模型-无锁

  • CAS与volatile
  • 原子整数
  • 原子引用
  • 原子累加器
  • Unsafe

2.1CAS与volatile

/*** @program: springboot-demo-liuan* @description:* @author: Mr.Lh* @create: 2023-03-18 21:29**/
public class CasController {public static void main(String[] args) throws InterruptedException {Acout acout = new Acout(10000);acout.demo(acout);}
}class Acout {public AtomicInteger balance;public Acout(int count) {this.balance = new AtomicInteger(count);}public void with(Integer amout) {while (true) {int i = balance.get();int b = i - amout;if (balance.compareAndSet(i, b)) {break;}}}void demo(Acout acout) throws InterruptedException {for (int i = 0; i < 1000; i++) {new Thread(()->{acout.with(10);}).start();}Thread.sleep(1000);System.out.println(acout.balance.get());}
}

关键点是compareAndSet,它的简称是CAS,它必须是原子性的操作

CAS特点

CAS和volatile可以实现无锁并发,适用于线程数小,多核CPU的场景下

  • CAS是基于乐观锁的思想
  • synchronized是基于悲观锁的思想
  • CAS体现的是无锁并发,无阻塞并发

CAS缺点

  • ABA问题:A值变成了B,然后又从B值变回了A,而使用CAS并不会感知到这个情况
  • 自旋时间过长:单次CAS并一定能够成功,CAS配合循环来使用

原子整数

  • AtomicInteger
  • AtomicBoolean
  • AtomicLong

原子引用

  • AtomicReference(会有ABA的问题)
  • AtomicStampedReference(版本号解决ABA的问题)

3.线程池

1.线程池状态

ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量

状态名高 3 位接收新任务处理阻塞队列任务说明
RUNNING111YY
SHUTDOWN000NY不会接收新任务,但会处理阻塞队列剩余 任务
STOP001NN会中断正在执行的任务,并抛弃阻塞队列 任务
TIDYING010--任务全执行完毕,活动线程为 0 即将进入 终结
TERMINATED011--终结状态
2.构造方法
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) 
  • corePoolSize 核心线程数
  • maximumPoolSize 最大线程数
  • keepAliveTime 生存时间
  • unit 生存时间单位
  • workQueue 当核心线程数满时,存放的任务队列
  • threadFactory 创建线程的工厂
  • handler 拒绝策略
四种策略
  • CallerRunsPolicy 让调用者运行任务
  • DiscardOldestPolicy 放弃队列中最早的任务,本任务取而代之
  • AbortPolicy 让调用者抛出异常 默认策略
  • DiscardPolicy 放弃本次任务
工厂创建线程
1.newFixedThreadPool

特点:

  • 核心线程数==最大线程数,无需超时时间
  • 阻塞队列是无界的,可以任意数量的任务
2.newCachedThreadPool

特点:

  • 核心线程数是0,最大线程数无限制,60s回收救急线程,救济线程可以无限的创建
  • 队列采用的SynchronousQueue 没有容量,没有线程来取是放不进去的
  • 没有上限的一个线程池
3.newSingleThreadExecutor

特点

  • 线程数固定为1,会放入无界队列中,任务执行完毕,这唯一的线程也不会被释放
任务调度线程池
//延时执行任务
public class TimeExcetor {public static void main(String[] args) {ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);scheduledExecutorService.schedule(() -> {System.out.println("aaaa");}, 2, TimeUnit.MILLISECONDS);scheduledExecutorService.schedule(() -> {System.out.println("bbbbbb");}, 1, TimeUnit.MILLISECONDS);}
}//定时执行任务
@Slf4j
public class TimeExcetor {public static void main(String[] args) {ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);log.debug("start...");pool.scheduleAtFixedRate(() -> {log.debug("running...");}, 1, 1, TimeUnit.SECONDS);}
}
正确处理执行任务异常
  • 主动捕获异常

    public static void main(String[] args) {ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);scheduledExecutorService.execute(() -> {try {int i = 10 / 0;} catch (Exception ex) {ex.printStackTrace();}System.out.println("aaa");});
    }
    
  • Future

    public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(2);Future<Boolean> submit = executorService.submit(() -> {int i = 10 / 0;return true;});//如果任务执行成功则获取值,如果任务失败了 则会打印出异常信息System.out.println(submit.get());
    }
    

4.JUC

4.1 AQS原理

AbstractQueuedSynchronizer,是一个用于实现锁和同步器的基础框架

特点:

  • state state 表示同步状态(分独占锁和共享锁) 使用compareAndSetState机制实现加锁
  • Node表示队列元素,每个 Node 对象内都保存着当前线程的引用,这些 Node 构成了一个双向队列
4.2ReentrantReadWriteLock

ReentrantReadWriteLock 同样基于 AQS 实现了一套高效的同步机制。它维护着两个锁,一个读取锁和一个写入锁。读取锁允许多个线程同时共享读操作,而写入锁则只允许一个线程进行写入操作。如果有一个线程已经获取了写入锁,那么其他所有线程都无法获得读取或写入锁,它们只能等待写入锁被释放后才能进行读取或写入操作。

4.3Semaphore

是一种在并发编程中经常使用的同步原语。它可以用来管理一组共享的资源,防止共享资源的并发使用。Semaphore包含一个计数器和两个方法:acquire和release

@Slf4j
public class SemaphoreDemo1 {public static void main(String[] args) {Semaphore semaphore = new Semaphore(2);for (int i = 0; i < 10; i++) {new Thread(()->{try {semaphore.acquire();log.info("获取信号量");Thread.sleep(10002);} catch (InterruptedException e) {throw new RuntimeException(e);}finally {semaphore.release();}}).start();}}
}

4.4CountDownLatch

是一个同步工具,它可以让一个线程等待一组操作的完成。CountDownLatch包含一个计数器和两个方法:countDown和await

countDown方法将计数器的值减一,await方法阻塞线程,直到计数器值为零。每次调用countDown方法都会减少计数器的值,当计数器值为零时,await方法会解除所有等待线程的阻塞状态

@Slf4j
public class CountDownLatchDemo1 {public static void main(String[] args) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(3);new Thread(()->{try {Thread.sleep(1000);countDownLatch.countDown();} catch (InterruptedException e) {throw new RuntimeException(e);}}).start();new Thread(()->{try {Thread.sleep(2222);} catch (InterruptedException e) {throw new RuntimeException(e);}countDownLatch.countDown();}).start();new Thread(()->{try {Thread.sleep(3333);} catch (InterruptedException e) {throw new RuntimeException(e);}countDownLatch.countDown();}).start();//主线程阻塞countDownLatch.await();}
}

4.5CyclicBarrier

循环栅栏,用来进行线程协作,等待线程满足某个计数。构造时设置『计数个数』,每个线程执 行到某个需要“同步”的时刻调用 await() 方法进行等待,当等待的线程数满足『计数个数』时,继续执行

public class CyclicBarrierDemo {public static void main(String[] args) {CyclicBarrier cb = new CyclicBarrier(2); // 个数为2时才会继续执行new Thread(()->{System.out.println("线程1开始.."+new Date());try {cb.await(); // 当个数不足时,等待} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}System.out.println("线程1继续向下运行..."+new Date());}).start();new Thread(()->{System.out.println("线程2开始.."+new Date());try { Thread.sleep(2000); } catch (InterruptedException e) { }try {cb.await(); // 2 秒后,线程个数够2,继续运行} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}System.out.println("线程2继续向下运行..."+new Date());}).start();}
}

相关文章:

并发编程-Day2

并发编程 1.共享模型-内存 共享变量在多线程间的<可见性>问题与多条指令执行时的<有序性>问题 1.1Java内存模型 JMM它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存CPU指令优化等. JMM体现在&#xff1a; 原子性-保证指令不会受到线程上…...

第1章 Nginx简介

基于 Nginx版本 1.14.2 &#xff0c;Tomcat版本 9.0.0 演示 第1章 Nginx简介 1.1 Nginx发展介绍 Nginx &#xff08;engine x&#xff09; 是一个高性能的Web服务器和反向代理服务器&#xff0c;也可以作为邮件代理服务器。 Nginx 特点是占有内存少&#xff0c;并发处理能力…...

一个.Net功能强大、易于使用、跨平台开源可视化图表

可视化图表运用是非常广泛的&#xff0c;比如BI系统、报表统计等。但是针对桌面应用的应用&#xff0c;很多报表都是收费的&#xff0c;今天给大家推荐一个免费.Net可视化开源的项目&#xff01; 项目简介 基于C#开发的功能强大、易于使用、跨平台高质量的可视化图表库&#…...

浅谈 ext2 文件系统的特点、优缺点以及使用场景

ext2&#xff08;Extended File System 2&#xff09;是 Linux 中最早的一种文件系统&#xff0c;它是 Linux 文件系统的基础&#xff0c;也被广泛用于其他类 Unix 系统中。下面是 ext2 文件系统的特点、优缺点以及使用场景&#xff1a; 特点&#xff1a; ext2 文件系统可以支…...

Map和Set数据结构和ES6模块化语法

Map和Set数据结构 ●ES6 新增的两种数据结构 ●共同的特点: 不接受重复数据 Set数据结构 ●是一个 类似于 数组的数据结构 ●按照索引排列的数据结构 创建 Set 数据结构 语法: var s new Set([ 数据1, 数据2, 数据3, ... ]) Set 数据结构的属性和方法 ●size 属性 ○语法: 数…...

10_Uboot启动流程_2

目录 _main函数详解 board_init_f函数详解 relocate_code函数详解 relocate_vectors函数详解 board_init_r 函数详解 _main函数详解 在上一章得知会执行_main函数_main函数定义在文件arch/arm/lib/crt0.S 中,函数内容如下: 第76行,设置sp指针为CONFIG_SYS_INIT_SP_ADDR,也…...

python+django汽车4S店零配件保养服务管理系统

汽车4S服务管理系统包括三种用户。管理员、普通员工、客户。 开发语言&#xff1a;Python 框架&#xff1a;django/flask Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyCharm django 应用目录结构管…...

STM32F4的输出比较极性和PWM1,PWM2的关系

PWM 输出比较通道 在这里以通用定时器的通道1作为介绍。 如图&#xff0c;左边就是CNT计数器和CCR1第一路的捕获/比较寄存器&#xff0c;它俩进行比较&#xff0c;当CNT>CCR1, 或者CNTCCR1时&#xff0c;就会给输出模式控制器传送一个信号&#xff0c;然后输出模式控制器就…...

易优cms伪静态,EyouCms去除URL中的index.php

针对不同服务器、虚拟空间,运行PHP的环境也有所不同,目前主要分为:Nginx、apache、IIS以及其他服务器。下面分享如何去掉URL上的index.php字符,记得在管理后台清除缓存,对于一些ECS服务器可能要重启nginx等服务! 【Nginx服务器】 在原有的nginx重写文件里新增以下代码片…...

【自然语言处理】【大模型】CodeGeeX:用于代码生成的多语言预训练模型

CodeGeeX&#xff1a;用于代码生成的多语言预训练模型 《CodeGeeX: A Pre-Trained Model for Code Generation with Multilingual Evaluations on HumanEval-X》 论文地址&#xff1a;https://arxiv.org/pdf/2303.17568.pdf 相关博客 【自然语言处理】【大模型】CodeGen&#x…...

Open3D 非线性最小二乘拟合二维多项式曲线

目录 一、算法原理二、代码实现三、结果展示一、算法原理 多项式曲线表示为: p ( x ) = p 1 x n + p 2 x n...

kafka消息队列的两种模式

第一种模式&#xff1a; 点对点模式&#xff08;一对一&#xff0c;消费者主动拉取数据&#xff0c;消息收到后消息清除&#xff09; 1.消息生产者生产消息发送给队列&#xff0c;然后消费者从队列中取出并且消费消息 2.消息被消费以后&#xff0c;queue中不再有存储&#xff0…...

python语法复习

print&#xff1a;输出函数 print(520)效果&#xff1a;输出520. print(hello)效果&#xff1a;输出hello. print(1020)【效果&#xff1a;输出了:1020】注&#xff1a;“ ”在print里面是一个连接符。 print(1020)【效果&#xff1a;输出了30】注&#xff1a; 在此处…...

02-Java基础编程

Java基础编程 Java 基础语法Java 标识符变量变量的类型Java 基本数据类型基本数据类型转换 运算符常见运算符运算符的优先级 程序流程控制分支语句循环结构常用的循环结构循环的嵌套break 和 continue 关键字 数组一维数组多维数组的使用Arrays 工具类的使用数组中常见的异常 J…...

武忠祥老师每日一题||定积分基础训练(十)

已知f(x)连续 ∫ 0 x t f ( x − t ) d t 1 − cos ⁡ x , 求 ∫ 0 π 2 f ( x ) d x 的值。 \int_{0}^{x}tf(x-t)\,{\rm d}t1-\cos x,求\int_{0}^{\frac{\pi}{2}}f(x)dx的值。 ∫0x​tf(x−t)dt1−cosx,求∫02π​​f(x)dx的值。 已知一个关于f的变上限积分等式&#xff0c;&…...

C/C++趣味程序设计百例(41~50)

C/C语言经典、实用、趣味程序设计编程百例精解&#xff08;5&#xff09; 41.马克思手稿中的数学题 马克思手稿中有一道趣味数学问题&#xff1a;有30个人&#xff0c;其中有男人、女人和小孩&#xff0c;在一家饭馆吃饭花了50先令&#xff1b;每个男人花3先令&#xff0c;每个…...

论文阅读-2-DeepSMOTE Fusing Deep Learning and SMOTE for Imbalanced Data

文章目录 Abstract1. Introduction2. Learning From Imbalanced Data1. 数据级2. 算法级3. 集成方法 3. Deep Learning From Imbalanced Data基于深度神经网络的实例生成损失函数适应长尾识别 4. DeepSMOTEA. 动机B. 描述C. encoder-decoder框架D. 增强的损失函数E. 人工图像生…...

三种方法教你让模糊照片秒变高清图

现在随着数字相机和智能手机的普及&#xff0c;我们拍摄的照片数量越来越多&#xff0c;但是有些照片可能因为环境或技术等原因导致模糊不清&#xff0c;这时候我们就需要使用一些软件或工具来让照片变得清晰&#xff0c;以满足我们的需求。 下面介绍三种常用的照片变清晰的方…...

PyTorch深度学习实战 | 基于线性回归、决策树和SVM进行鸢尾花分类

鸢尾花数据集是机器学习领域非常经典的一个分类任务数据集。它的英文名称为Iris Data Set&#xff0c;使用sklearn库可以直接下载并导入该数据集。数据集总共包含150行数据&#xff0c;每一行数据由4个特征值及一个标签组成。标签为三种不同类别的鸢尾花&#xff0c;分别为&…...

服务端接口优化方案

一、背景 针对老项目&#xff0c;去年做了许多降本增效的事情&#xff0c;其中发现最多的就是接口耗时过长的问题&#xff0c;就集中搞了一次接口性能优化。本文将给小伙伴们分享一下接口优化的通用方案。 二、接口优化方案总结 1. 批处理 批量思想&#xff1a;批量操作数据…...

告别命令行!用Python脚本批量管理Docker容器,效率提升不止一点点

告别命令行&#xff01;用Python脚本批量管理Docker容器&#xff0c;效率提升不止一点点每次在终端敲入docker ps、docker stop、docker rm时&#xff0c;你是否想过——当容器数量超过两位数&#xff0c;这种重复劳动是否在消耗你的生命&#xff1f;去年我们团队在迁移微服务架…...

Windows 10/11系统下,SecureCRT 8.7.2保姆级安装与激活图文指南(含Keygen使用避坑点)

Windows平台SecureCRT 8.7.2全流程部署与安全配置指南在当今远程运维与网络管理的日常工作中&#xff0c;一款可靠的终端仿真工具如同工程师的瑞士军刀。作为行业标杆的SecureCRT&#xff0c;其8.7.2版本在Windows 10/11环境下的部署却常让新手陷入各种技术陷阱——从安装路径选…...

基于ESP32与MQTT的家庭环境监测系统:从传感器选型到数据可视化实战

1. 项目概述与核心价值最近几年&#xff0c;我身边越来越多的朋友开始关注家里的空气质量、温湿度这些看不见摸不着&#xff0c;但又实实在在影响生活舒适度和健康的环境指标。从新装修的房子担心甲醛&#xff0c;到有老人小孩的家庭在意PM2.5和二氧化碳浓度&#xff0c;再到南…...

XZ1018,100V,40A,NMOS 封装:TO252

封装&#xff1a;TO252类型&#xff1a;NVDS&#xff1a;100V VGS&#xff1a; 20V ID&#xff1a;40ARDS(ON)&#xff1a;10V <14mΩRDS(ON)&#xff1a;4.5V <19mΩ型号&#xff1a; XZ1018 封装&#xff1a;TO252类型&#xf…...

收藏|2026年AI大模型就业爆发!岗位暴涨12倍、月薪6W+,小白零基础入门指南

2026年&#xff0c;AI已从“科技热点”彻底变为职场“刚需赛道”&#xff01;脉脉高聘人才智库最新发布的《2026年1-2月中高端人才求职招聘洞察》&#xff0c;用硬核数据揭示行业真相&#xff1a;AI人才成招聘市场顶流&#xff0c;岗位量、薪资双双爆发式增长。尤其对零基础小白…...

基于Atmega 1284P的16位复古计算器:硬件设计与软件实现全解析

1. 项目概述与核心思路最近在整理工作室时&#xff0c;翻出了一堆老旧的7段数码管和矩阵键盘&#xff0c;看着这些充满复古气息的元件&#xff0c;一个想法冒了出来&#xff1a;为什么不自己动手做一台复古风格的计算器呢&#xff1f;不是那种用液晶屏显示的现代计算器&#xf…...

开源三角洲机器人Delta-Robot One:从入门到精通的创客实践指南

1. 项目概述&#xff1a;一个为学习而生的开源三角洲机器人如果你对机器人感兴趣&#xff0c;但又觉得它高深莫测、无从下手&#xff0c;那么Delta-Robot One&#xff08;我们亲切地称它为“One”&#xff09;可能就是为你量身打造的入门项目。这不是一个遥不可及的工业设备&am…...

抖音批量下载助手:一键构建你的专属视频素材库

抖音批量下载助手&#xff1a;一键构建你的专属视频素材库 【免费下载链接】douyinhelper 抖音批量下载助手 项目地址: https://gitcode.com/gh_mirrors/do/douyinhelper 还在为手动保存抖音视频而烦恼吗&#xff1f;想要批量获取心仪创作者的精彩内容却无从下手&#x…...

在ubuntu上为node.js后端服务接入taotoken统一大模型api

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 在 Ubuntu 上为 Node.js 后端服务接入 Taotoken 统一大模型 API 为后端服务集成大模型能力已成为提升应用智能水平的关键步骤。对于…...

VMnet8 的8到底是什么意思?

它的本质是&#xff1a;8 仅仅是一个 内部标识符 (Internal Identifier) 或 数组索引 (Array Index)&#xff0c;用于在 VMware 的虚拟化网络栈中唯一标识 NAT 模式 对应的虚拟交换机实例。它没有任何数学、物理或协议层面的特殊含义&#xff08;如端口号、版本号或二进制位&am…...