Java多线程进阶详解

CAS的ABA问题

使用CAS编写代码,比较然后交换。

大部分没问题,但在极端情况下有问题。

比如银行取钱一个人账户是1000,取款500,假设是按照CAS的方式来执行的。按取款卡了一下,又按了一下。就有两个线程来进行操作,如果恰好有人转账500,则会出现bug。

如何处理ABA问题呢?使用账户余额判定,本身就不科学。属于能加也能减。引入一个只能加的版本号,每次取钱或者存钱,版本号就+1,就可以进一步解决ABA问题。CAS的核心就在于说,通过数值没变=》中间没有别的线程覆盖。

JUC中的常见类

java.util.concurrent 放了和多线程相关的组件。

callable接口(也是描述一个任务,call有返回值)Runnable描述一个任务没有返回值(run方法是返回void)

比如对一个值增加的时候

package Thread;public class Demo26 {public static int sum=0;public static void main(String[] args) throws InterruptedException {Thread t1=new Thread(new Runnable() {@Overridepublic void run() {int result=0;for (int i = 1; i <= 1000; i++) {result+=i;}sum=result;}});t1.start();t1.join();System.out.println(sum);}}

这串代码的耦合非常高

如果运用Callable接口的话

package Thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class Demo27 {public static void main(String[] args) throws InterruptedException, ExecutionException {Callable<Integer> callable=new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int result=0;for (int i = 1; i <= 1000; i++) {result+=i;}return result;}};FutureTask<Integer> futureTask=new FutureTask<>(callable);Thread t=new Thread(futureTask);t.start();t.join();System.out.println(futureTask.get());}
}

这串代码就降低了耦合

futureTask就相当于发票一样。

ReentrantLock(可重入锁)

ReentrantLock的价值:

1.ReentrantLock提供了公平锁的实现。

synchronized只是非公平锁

ReentrantLock locker=new ReentrantLock(true);

写true就是公平形态。写false或者不写就是非公平锁。

2..ReentrantLock提供tryLock操作,给加锁提供了更多的课操作空间。

尝试加锁,如果锁已经被获取到了,直接返回失败,而不会继续等待。

synchronized都是遇到锁竞争,就阻塞等待(死等)

tryLock除了直接返回这种形态之外,还有一个版本,可以指定等待超时时间。

3.synchronized 是搭配wait notify等待通知机制。

ReentrantLock是搭配Condition类完成等待通知。

Condition要比wait notify更强一点(多个线程wait,notify是唤醒随机的一个,Conditon指定线程唤醒)

信号量Semaphore

信号量就是一个计数器

信号量有两个基本操作

1,P操作

2,V操作

CountDownLatch(相对来说比较实用的工具类)

当我们把一个任务拆分分成很多个的时候,就可以通过这个工具类来识别任务是否整体执行完毕了

package Thread;import java.util.concurrent.CountDownLatch;public class Demo28 {public static void main(String[] args) throws InterruptedException {CountDownLatch latch =new CountDownLatch(10);for (int i = 0; i < 10; i++) {int id=i;Thread t=new Thread(() ->{System.out.println("线程启动"+id);try{//假设这里是进行一些下载操作Thread.sleep(3000);}catch(InterruptedException e){throw new RuntimeException(e);}System.out.println("线程结束"+id);latch.countDown();});t.start();}//通过await等待所有的线程调用countDownlatch.await();System.out.println("所有线程结束");}
}

await会阻塞等待,一直到countDown调用的次数。和构造方法指定的次数一致的时候,await才会返回。

CopyOnWriteArraylist也是一种解决线程问题安全的做法(写时拷贝)

如果当前有多个线程去读,此时不需要做任何处理。

假设某个线程要对上面的数据进行修改。修改的同时,很多的线程在读呢,如果直接修改,不加任何处理,意味着有的线程会有中间情况。

写完之后,用新的数组的引用,代替旧的数组的引用。

(引用赋值操作,是原子的)

上述过程,没有任何加锁和阻塞等待,也能确保线程不会读出“错误的数据”,旧的空间可以释放了。

多线程使用队列

直接使用BlockkingQueue即可。

多线程使用哈希表.

HashMap是线程不安全的,Hashtable是带锁的,但不推荐使用。

标准库提供了更好的替代,ConcurrentHashMap

ConcurrentHashMap做出了优化

1.使用“铁桶”的方式,来替代“一把全局锁”,有效降低锁冲突的概率。

2.像hash表的size,即使你插入的元素是不同的俩表==链表上的元素,也会设计到多线程修改同一个变量。

引入CAS,通过CAS的方式,来修改size,也就避免了加锁操作。

3.针对扩容操作做了特殊优化。

如果发现,负载因子太大了,就需要扩容,扩容是一个比较重量比较低效的操作。

普通的hashmap要在一次put的过程中,完成整个扩容过程。

就会使put操作非常ka。

coucurrentHashmap会在扩容的时候,搞两份空间。

一份是之前扩容之前的空间。

一份是扩容之后的空格。

接下来每次进行hash表的基本操作,都会把一部分数据从旧空间搬运到新空间。

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

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

相关文章

PowerBI 无法拖动字段到组件上

今天在做PowerBI时发现一个奇怪的问题。 本来好好的报表&#xff0c;突然无法拖动字段到组件上。 后来在网上搜索相关问题&#xff0c;发现原因可能是因为"隐式度量值"被禁用。 就是说报表无法自动聚合计算&#xff0c;所以无法拖动字段到组件上。 正确的: 有问题…

熟食店称重计价秤软件下载 佳易王触摸屏称重自动读取重量自动计算金额系统操作教程

一、概述 【软件资源文件下载在文章最后】 熟食店称重计价秤软件下载 触摸屏称重自动读取重量自动计算金额系统操作教程 1、软件可以自动读取称的重量。2、自动计算金额并累计。不需打印条形码直接称重计算&#xff0c;节省人力和时间。 软件同时支持称重商品和条形码百货商…

十一 手写Spring框架

十一、手写Spring框架 Spring IoC容器的实现原理&#xff1a;工厂模式 解析XML 反射机制。 我们给自己的框架起名为&#xff1a;loveSpring 第一步&#xff1a;创建模块loveSpring 采用Maven方式新建Module&#xff1a;loveSpring 打包方式采用jar&#xff0c;并且引入do…

360多模态及文档理解大模型技术亮相全球机器学习技术大会,共探AI技术新前沿...

北京&#xff0c;2024年11月15日 —— 在人工智能技术飞速发展的今天&#xff0c;全球技术生态正经历着深刻的变革。2024全球机器学习技术大会&#xff08;北京站&#xff09;于11月14-15日在北京举行&#xff0c;汇聚了顶尖的AI专家、学者和行业实践者&#xff0c;共同探讨机器…

六自由度双足机器人运动控制

最近迷上了研究机器人&#xff0c;花了很多时间研究机器人的控制和交互。先后开发出来了四足四自自由度&#xff0c;四足八自由度&#xff0c;两足四自由度&#xff0c;两足六自由度机器人&#xff0c;并为他们开发了相应的大模型语音交互。通过努力&#xff0c;既锻炼了动手组…

shell脚本(2)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;shell编程&#xff08;2&#xff09;永久环境变量和字符串显位_哔哩哔哩_bilibili 本文主要讲解临时变量和永久变量以及字符串长度截取操作。 一…

SEW MDX61B 变频器调试说明

SEW MDX61B 变频器调试说明 1、打开MOVITOOLS MotionStudio软件 2、创建新项目(可根据需求更改项目名称及保存路径) 新建完成 3、电机初始化 连接新变频器和新电机时,必须进行电机初始化。电机初始化目的为配对电机参数至变频器,简单说就是让变频器知道需要控制的是什么…

【软件测试】设计测试用例的万能公式

文章目录 概念设计测试用例的万能公式常规思考逆向思维发散性思维万能公式水杯测试弱网测试如何进行弱网测试 安装卸载测试 概念 什么是测试用例&#xff1f; 测试⽤例&#xff08;Test Case&#xff09;是为了实施测试⽽向被测试的系统提供的⼀组集合&#xff0c;这组集合包…

泛微OA 请求外部数据源

1 .oa 外部数据源配置好 取数据源名称 引用key 固定写法 datasource.A_nc datasource.数据源名称 getConnection("datasource.A_nc",xf);//A账 2 引用方式 package weaver.interfaces.jphr;import java.io.UnsupportedEncodingException; import java.sql.Conne…

深度学习基础—Bleu得分

引言 机器翻译任务中&#xff0c;通常会需要评价指标来评估机器翻译的好坏。仅通过统计翻译词在标准翻译中出现的次数这种方式很不合理&#xff0c;就需要用到Bleu得分来进行评估。 1.n-gram&#xff08;N元组&#xff09; 假设要翻译&#xff1a;Le chat est sur le tapis&am…

794: 最近对问题

解法&#xff1a; #include<bits/stdc.h> using namespace std; const int N1e33; struct P{int x,y; }a[N]; int main(int argc, char** argv) {int t,n;cin>>t;while (t--){cin>>n;for (int i0;i<n;i) cin>>a[i].x>>a[i].y;double dis,mn1…

Vue基础(1)_模板语法、数据绑定

模板语法 Vue模板语法有2大类&#xff1a; 1、插值语法&#xff1b; 功能&#xff1a;用于解析标签体内内容。 写法&#xff1a;{{xxx}}&#xff0c;xxx是js表达式&#xff0c;且可以直接读取到data中的所有属性。 2、指令语法&#xff1a; 功能&#xff1a;用于解析标签(包括…

如何清洗电水壶中的水垢亲自实践

以前看过很多生活小妙招&#xff0c;什么柠檬啊&#xff0c;白醋啊&#xff0c;土豆片啊&#xff0c;都测试过。没有用。因为自来水很硬&#xff0c;钙比较重。 钙覆盖在水壶底部&#xff0c;烧水就滋滋得响&#xff0c;而且效率变低。 昨天买洁厕剂&#xff0c;看到一种除垢…

LC13:滑动窗口

文章目录 1052. 爱生气的书店老板 这个专栏记录自己刷题碰到的有关滑动窗口的题目。 1052. 爱生气的书店老板 题目链接&#xff1a;1052. 爱生气的书店老板 第一感应该是滑动窗口可以解决的&#xff0c;随后思考并写了几个版本&#xff0c;最终版本实现结合滑动窗口一次遍历…

酒店管理系统(源码+文档+部署+讲解)

本文将深入解析“酒店管理系统”的项目&#xff0c;探究其架构、功能以及技术栈&#xff0c;并分享获取完整源码的途径。 系统概述 酒店管理系统是一款为酒店行业设计的全面管理软件&#xff0c;旨在通过集成酒店运营的各个关键环节&#xff0c;提高酒店的管理效率和客户满意…

D3开发的基本框架步骤

D3.js 是一个功能强大的数据可视化库&#xff0c;用于在网页上创建复杂的图表和交互式图形。以下是一个基本的 D3.js 开发框架&#xff0c;包括了常见的步骤和代码示例&#xff0c;帮助你快速入门。 基本框架 引入 D3.js 库设置 SVG 容器加载数据创建比例尺绘制图形添加轴添加…

正则表达式完全指南,总结全面通俗易懂

目录 元字符 连接符 限定符 定位符 修饰符&#xff08;标记&#xff09; 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 正则表达式在线测试: 正则在线测试工具 元字符 字符描述\d 匹配一个数字字符。等价于 …

对象的初步认识

#对象可组织数据&#xff08;如统计数据的表格&#xff09; 下以表格为例 1.设计一个表格:(None为初始值设定&#xff0c;表示无) class a; ##1None ##2None 2.创建一个表格 变量a 3.对对象的属性进行赋值 变量.##1"##" 变量.##2"##" 4.查询对象中…

Linux驱动开发第1步_了解STM32MP157D

了解STM32MP157D有哪些硬件资源&#xff0c;为以后进行Linux驱动开发做准备。 STM32MP157A/D器件基于高性能双核ArmCortex-A7 32位RISC内核&#xff0c;工作频率高达800 MHz。Cortex-A7处理器&#xff1a;每个CPU具有32kbyte L1指令缓存&#xff0c;每个CPU具有32kbyte L1数据…

w039基于Web足球青训俱乐部管理后台系统开发

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0…