并发编程三大特性之原子性

一、并发编程3大特性是什么?

       并发编程三大特性分别是原子性、可见性和有序性。java内存模型JMM就是围绕着原子性、

       可见性、原子性来处理java线程间通信的。

二、原子性

       1、什么是原子性?

                   原子性是指一个操作是不可分割的,不可终端的;一个线程执行时,另一个线程

             不会影响到它 ,即多线程操作临界资源,预期结果要与最终结果一致。

             如:赋值操作 a=1 是原子操作,但注意 i++/i--、++j/--j 不是原子操作,

                   以下边代码举例说明:

public class Test01 {private static int count = 0;public static void increment() {count++;try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for(int i=0;i<100;i++){increment();}});Thread t2 = new Thread(() -> {for(int i=0;i<100;i++){increment();}});t1.start();t2.start();//主线程(这里是main线程)阻塞,等待t1、t2执行完成后主线程(main线程)才继续往下执行t1.join();t2.join();//若count++是原子的,那么最后count一定输出200,否则说明count++不是原子性的System.out.println(count);}
}

                   当前程序多线程操作时,最终结果与预期结果不一致

           2、通过javap 反编译java字节码文件来观察i++操作的执行过程

                 1)在当前文件下执行命令 javac  java文件,将java文件编译成字节码文件,

                        即.class 文件,如Test01.class

                 2)执行 javap -v Test01.class 命令,反编译字节码文件,i++ 的执行过程如下:

                       

                       可以看到i++的操作分了3个步骤,即如上图所示分别是:从主内存中取变量、

                      在线程私有本地内存中计算、最后把计算结果刷新到主内存

         3、如何保证原子性?

              3.1)通过synchronized关键字 保证原子性

                       可以在方法上添加关键字或在方法中使用synchronized 同步代码块来保证原子性。

                       synchronized 可以避免多个线程同时操作临界资源,同一时间点只有一个线程在

                       操作临界资源。

                       以使用同步代码块为例,如下所示:

public  static int count = 0;public void increment(){synchronized (this){count++;}}

                        

                     java文件编译后,monitorenter指令插入到代码块开始的位置,表示获取了锁;

                       而 monitorexit 指令插入到代码块结束或异常的位置,表示释放锁。

                       jvm保证每个 monitorenter指令 都有一个 monitorexit 指令 与其对应

              3.2)CAS 保证原子性

                       (1)什么是CAS

                                 compare  and swap(简称CAS)也就是比较和交换,是一条CPU层面

                                 上的并发源语,在cpu层面上执行。它在替换内存中某个位置的值时,首先

                                 会查看该位置的值是否与预期的值一致,若一致则交换;这个操作是原子的

                                  java中基于Unsafe的类提供了对CAS的操作方法,jvm会帮助我们将方法实现

                                  编译成CAS汇编指令。

                                  注意:CAS只是比较和交换,但从内存中取变量需要自己实现;

                                             CAS只能保证一个变量的原子性,不能保证多行代码的原子性

                        (2)使用CAS保证原子性,示例代码如下:

                                  

public static AtomicInteger count = new AtomicInteger(0);public static void increment(){//自增count.incrementAndGet();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}

                 3.3)使用Lock 锁来保证原子性,示例代码如下:

                          

                           

                 3.4)使用ThreadLocal保证原子性

                           ThreadLocal保证原子性的方式是不让多线程去操作临界资源,让每个线程操作

                           自己私有本地内存中的资源(即操作自己的数据,不操作共享数据)

                           示例代码如下:

                                    

                       ThreadLocal 实现原理:

                               1)每个Thread中都存储着一个成员变量ThreadLocalMap,用与存放与其关联

                                     的ThreadLocal,ThreadLocal绑定的是当前线程

                                     ThreadLocal的set/get方法如下图:

                                           

                                           

                               2)ThreadLocal 本身不存储数据,像是一个工具类,基于ThreadLocal去操作

                                     ThreadLocalMap

                               3)ThreadLocalMap本身就是基于Entry[] 实现的,因为一个线程可以绑定多个

                                     ThreadLocal,这样一来可能需要存储多个数据,所以采用Entry[] 形式实现

                               4)每个Thread 都有自己独立的 ThreadLocalMap ,再基于ThreadLocal 对象

                                     本身作为key,对value进行存取

                                5)ThreadLocalMap的key是一个弱引用,若引用的特点是:对象即使存在弱

                                      引用,在GC时,也必须被回收。这里弱引用是为了解决在ThreadLocal对

                                      象失去引用后,如果key的引用是强引用,会导致ThreadLocal对象无法

                                      回收的问题,即弱引用是为了解决ke内存泄漏的问题。

                               ThreadLocal 存储结构图如下:

                                           

                         ThreadLocal 内存泄漏的问题:

                                   1)什么是  ThreadLocal 内存泄漏?

                                         如果 ThreadLocal 引用丢失,key因为弱引用会被GC回收掉,如果同时

                                         线程还没有被回收,就会导致内存泄漏,内存中的value无法被回收,同

                                          时也无法被获取到。

                                    2) 如何解决 ThreadLocal 内存泄漏?

                                           只需要在使用完  ThreadLocal 对象之后,及时调用 ThreadLocal 的

                                           remove() 方法把 ThreadLocal 的值从 Entry 删除。

                                           ThreadLocal的 remove方法如下:

                                                  

                                      

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

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

相关文章

想要孩子对你敞开心扉,就别再做这件事情了

短篇日记 今天晚上&#xff0c;发生了几件小事&#xff0c;让我明白&#xff0c;与孩子真诚沟通比说教要强一万倍。 第一件事情&#xff1a;晚上我下班回来&#xff0c;俩宝都在小区边玩边等我。 玩儿了一会儿觉得有点冷&#xff0c;我们就打算回家。 回家途中&#xff0c;…

B/S结构和C/S结构详细介绍

文章目录 什么是c/s结构、b/s结构c/s结构b/s结构 b/s结构和c/s结构各自的优点&#xff1a;数据放在服务端和客户端的利与弊&#xff1f;c/s、b/s区别&#xff1a; 什么是c/s结构、b/s结构 1、C/S结构&#xff0c;即Client/Server(客户机/服务器)结构&#xff0c;是大家熟知的软…

【智能排班系统】基于SpringSecurity实现登录验证、权限验证

文章目录 SpringSecurity介绍sss-security实现依赖工具类Jwt工具JSON响应工具加密工具类 用户上下文用户信息实体类用户上下文 自定义重写自定义无权限的报错自定义密码加密自定义用户类 过滤器登录过滤器权限过滤器 Service登录Service 配置类说明登录验证权限验证IP流量限制 …

【数据分析面试】12. 随机抽取颜色球(Python random模块应用:choices()/choice()/sample())

题目 随机抽取颜色球 编写一个函数来模拟从罐子中抽取球的过程。球的颜色存储在名为jar的列表中&#xff0c;每个颜色对应球的数量存储在名为n_balls的列表中&#xff0c;且数量与颜色列表的索引对应。 示例&#xff1a; 输入&#xff1a; jar [green, red, blue] n_bal…

【XCPC笔记】2023 (ICPC) Jiangxi Provincial Contest——ABCHIJKL 做题记录

赛后gym练习及补题&#xff0c;gym链接&#xff1a;2023 (ICPC) Jiangxi Provincial Contest – Official Contest 补题顺序 L [Zhang Fei Threading Needles - Thick with Fine](https://codeforces.com/gym/104385/problem/L)题面解读参考代码 A [Drill Wood to Make Fire](h…

Ceph学习 - 2.分布式文件系统DFS

文章目录 1.分布式文件系统DFS1.1 DFS简介1.1.1 存储基础1.1.2 分布式文件系统1.1.3 DSS简介1.1.4 常见的文件系统 1.2 原理解读1.2.1 分布式数据存储1.2.2 存储角色1.2.3 数据高可用 1.3 小结 1.分布式文件系统DFS 学习目标&#xff1a;这一节&#xff0c;我们从DFS简介、原理…

ENSP防火墙配置内网NAT访问外网,内网发表web服务器

内网配置NAT访问外网 搭建拓扑 基础配置 cloud配置 配置防火墙web登录&#xff0c;配置web和设备命令行过期时间 Username:admin Password: // Admin123 The password needs to be changed. Change now? [Y/N]: Y Please enter old password: // Admin123 Please enter …

石油化工控制台定制厂家具备的专业条件一览

石油化工行业&#xff0c;作为国家的支柱产业之一&#xff0c;对设备与控制台的要求尤为严格。石油化工控制台是石油化工行业必不可少的办公设备之一。因此&#xff0c;选择一家专业的石油化工控制台定制厂家&#xff0c;对于提升企业的生产效率与安全水平具有不可估量的价值&a…

雷弗流体创新技术装备与您与您相约2024第13届生物发酵展

参展企业介绍 保定雷弗流体科技有限公司于2010年1月成立。为创新型企业&#xff0c;荣获国家级高新技术企业、国家级专精特新小巨人企业、河北省单项冠军企业、组织部巨人计划创业团队等荣誉称号。 保定雷弗流体科技有限公司现有职工180人&#xff0c;其中工程技术人员53人。现…

开发者关注的数据库技术与创新

开发者关注的数据库技术与创新 最近关注的数据库技术与创新有哪些对于未来数据库的演进有哪些思考开发者心目中最理想的数据库是什么样的 在引起对数据库话题的相关讨论之前&#xff0c;先来定位一下什么是数据库服务。那么什么是数据库服务呢&#xff1f;简单来说数据库服务的…

MFC扩展库BCGControlBar Pro v34.1 - 支持Windows 10/11字体图标

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v34.1已正式发布了&#xff0c;这个版本包含了对Windows 10/11字体图标的支持、功能区和…

微信聊天记录恢复只需简单3招,快速找回聊天内容!

各种社交软件早已深深融入我们的日常生活&#xff0c;无论是与亲朋好友的闲聊&#xff0c;还是与同事伙伴的工作沟通&#xff0c;都离不开它们的陪伴。然而&#xff0c;有时由于误操作、系统更新或手机故障等原因&#xff0c;我们可能会不小心删除了重要的聊天记录&#xff0c;…