Java多线程悲观锁和乐观锁

news2025/1/27 13:03:01

悲观锁:
一上来就加锁,没有安全感,每次只能一个线程进入访问完毕后,再解锁。 线程安全,性能较差

乐观锁:
一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题的时候才开始控制。 线程安全,性能较好

接下来我们通过案例,来分别实现三种情况:1、不加锁的情况,2、加悲观锁 3、加乐观锁。我们创建两个类来进行案例的演示,分别是Test类MyRunnable类。

1、不加锁的情况

MyRunnable类

package ThreadTzTest;

public class MyRunnable implements Runnable{
    private int count;//记录浏览人数
    @Override
    public  void run() {
        //100次
            for (int i = 0; i < 100; i++) {
                System.out.println("count======>"+(++count));
            }
    }
}

Test类

package ThreadTzTest;

public class Test {
    public static void main(String[] args) {
        //目标:拓展悲观锁、乐观锁原理
        //悲观锁:一上来就加锁,没有安全感,每次只能一个线程进入访问完毕后,再解锁。     线程安全,性能较差
        //乐观锁:一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题的时候才开始控制。   线程安全,性能较好


        //需求:1个静态变量,100个线程,每个线程对其加100次
        Runnable target = new MyRunnable();

        for (int i = 1; i <= 100; i++) {
            new Thread(target).start();

            
        }


    }
}

运行结果:
在这里插入图片描述
可以看到结果是不正确的,正确结果应该是10000,这是因为出现了线程安全问题。

2、添加悲观锁

MyRunnable类

package ThreadTzTest;

public class MyRunnable implements Runnable{
    private int count;//记录浏览人数
    @Override
    public  void run() {
        //100次
        synchronized (this) {
            for (int i = 0; i < 100; i++) {
                System.out.println("count======>"+(++count));
            }
        }

    }
}

Test类不变,我们再来看运行结果:
在这里插入图片描述
可以看到,添加悲观锁后线程正确运行了,没有出现线程安全问题。

3、添加乐观锁

package ThreadTzTest;

import java.util.concurrent.atomic.AtomicInteger;

public class MyRunnable2 implements Runnable{
    //整数修改的乐观锁,原子类实现的
    private AtomicInteger count = new AtomicInteger();


    @Override
    public  void run() {
        //100次
            for (int i = 0; i < 100; i++) {
                System.out.println("count======>"+count.incrementAndGet());
                //incrementAndGet()先加1再返回,在方法的内部没有加锁

            }
    }
}

package ThreadTzTest;

public class Test {
    public static void main(String[] args) {
        //目标:拓展悲观锁、乐观锁原理
        //悲观锁:一上来就加锁,没有安全感,每次只能一个线程进入访问完毕后,再解锁。     线程安全,性能较差
        //乐观锁:一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题的时候才开始控制。   线程安全,性能较好


        //需求:1个静态变量,100个线程,每个线程对其加100次
        Runnable target = new MyRunnable2();

        for (int i = 1; i <= 100; i++) {
            new Thread(target).start();

            
        }


    }
}

运行结果:
在这里插入图片描述
乐观锁实现原理:

先存下原来的值是多少,然后进行数据的操作,进行修改的时候判断存下来的值和现在的值是否相等,如果相等就把修改后的数据存进去

4、乐观锁案例

在这里插入图片描述

public class OptimisticLock {  
    private int version;  
    private String data;  
  
    public String readData() {  
        return data;  
    }  
  
    public boolean updateData(String newData) {  
        int currentVersion = version;  
        // 更新数据  
        data = newData;  
        version++;  
        // 检查版本号是否一致  
        if (currentVersion != version) {  
            // 版本号不一致,回滚事务  
            return false;  
        }  
        // 提交事务  
        return true;  
    }  
}

在这里插入图片描述

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

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

相关文章

SpringBoot--手写组件动态更新@Value的值

原文网址&#xff1a;SpringBoot--手写组件动态更新Value的值_IT利刃出鞘的博客-CSDN博客 简介 本文手写组件&#xff0c;动态更新SpringBoot里Value的值&#xff08;无需重启服务&#xff09;。 不是可以用RefreshScope吗&#xff1f;为什么要手写组件&#xff1f; 动态更…

docker数据卷+挂载(命令讲解+示例)

在容器中管理数据主要有两种方式&#xff1a; 数据卷&#xff08;Volumes&#xff09; 、挂载主机目录 (Bind mounts)。 一、数据卷 数据卷是一个可供一个或多个容器使用的特殊目录&#xff0c;可以在容器之间共享和重用。 特点&#xff1a; 对 数据卷 的修改会立马生效对 …

动态规划简述;斐波那契数列自顶向下和自底向上

概述 动态规划就是把一个问题分解为若干子问题&#xff0c;把子问题的解累加起来&#xff0c;就是当前问题的值。 斐波那契数列&#xff08;自顶向下&#xff09; 一个很好的演示demo&#xff0c; 在进行运算时&#xff0c;要用上备忘录&#xff08;缓存&#xff09;&#x…

从硬件结构到软件

先说说体系冯诺依曼的体系结构&#xff0c;有利于我们后面理解操作系统&#xff0c;软件再怎么发展&#xff0c;也必须遵守硬件的规则。 一 五大硬件理解 如下图: 1 为什么要有输入输出设备 很久以前&#xff0c;我们都是把指令打成孔&#xff0c;有孔无孔表示0,1&#xff0c…

柯桥日常口语学习|生活英语|实用口语口语天天练

1. How far is it from here? 离这儿有多远&#xff1f; 2. Can you give me a hand? 能帮帮我吗&#xff1f; 3. I cant lift my right arm. 我无法举起我的右手臂。 4. This bridge was built two years ago. 这座桥是在两年前建造的。 5. You should eat more. 你应该…

Go语言入门心法(一): 基础语法

Go语言入门心法(一) Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 一: go语言中变量认知 go语言中变量的定义: &#xff08;要想飞|先会走&#xff09;||&#xff08;翻身仗|抹遗憾 &#xff09; |&#xff08;二八定律&#xff09;(先量变)|(再质变)||&#xf…

vue3实现刻度尺

期望实现效果如下&#xff1a; 一、基本使用 安装slide-ruler&#xff0c;根据文档实现内容 https://github.com/wusb/slide-ruler/blob/master/README-zh_CN.md 二、进一步处理 1、直接复制slide-ruler核心文件&#xff0c;在此基础上进一步处理 处理1&#xff1a;刻度朝向…

思维模型 秩序

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。秩序是事物正常运行的基石。有序的安排是成功的先决条件。 1 秩序的应用 1.1 秩序在不同科学领域中的应用 物理学和天文学&#xff1a; 物理学家通过研究原子和分子的有序排列来理解物质的…

思维模型 正/反 木桶理论

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。 1 正/反 木桶理论的应用 1.1 木桶理论的应用 1.1.1 正木桶理论在考试中的应用 小明是一名理科高中生&#xff0c;他在学习过程中发现自己在数理化方面表现较好&#xff0c;但在语文和英…

基于Vue+webpack之H5打包资源优化

前言 基于公司的业务以及今年接触到的项目大部分都是APP混合开发&#xff0c;即原生Android/ios H 5页面开发APP。项目从产品需求的评审到方案的评审再到开发提测...这一套流程下来让我收货颇多。总想找个时间好好记录一番&#xff0c;大概还是自己懒惰了&#xff0c;一直拖到…

【Vue面试题二十二】、什么是虚拟DOM?如何实现一个虚拟DOM?说说你的思路

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;什么是虚拟DOM&#xff…

vim、gcc/g++、make/Makefile、yum、gdb

vim、gcc/g、make/Makefile、yum、gdb 一、Linux编辑器vim1、简介2、三种模式的概念&#xff08;1&#xff09;正常/普通/命令模式(Normal mode)&#xff08;2&#xff09;插入模式(Insert mode)&#xff08;3&#xff09;末行/底行模式(last line mode) 3、三种模式的切换4、正…

langchain 加载各种格式文件读取方法

参考&#xff1a;https://python.langchain.com/docs/modules/data_connection/document_loaders/ https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/blob/master/app.py 代码 可以支持pdf、md、doc、txt等格式 from langchain.document_loaders import Unstruct…

数据库管理-第109期 19c OCM考后感(20231015)

数据库管理-第109期 19c OCM考后感&#xff08;202301015&#xff09; 距离上一篇又过了两周多&#xff0c;为啥又卡了这么久&#xff0c;主要是后面几个问题&#xff1a;1. 9月1日的19c OCM upgrade考试木有过&#xff0c;因为有一次免费补考机会就又预约了10月8日的考试&…

IoT知识点补充

MySQL vs NoSQL数据库&#xff08;MongoDB&#xff09; 这里举的例子使用MySQL存储用户信息和博客文章的关系数据&#xff0c;同时使用MongoDB存储博客文章的评论&#xff0c;因为评论可以是不同结构的半结构化数据。 MySQL部分如下 import java.sql.Connection; import jav…

普冉PY32系列(九) GPIO模拟和硬件SPI方式驱动无线收发芯片XL2400

目录 普冉PY32系列(一) PY32F0系列32位Cortex M0 MCU简介普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单普冉PY32系列(四) PY32F002A/003/030的时钟设置普冉PY32系列(五) 使用JLink RTT代替串口输出日志普冉PY32…

初出茅庐的小李博客之SPI工作模式

SPI的工作模式 SPI&#xff08;Serial Peripheral Interface&#xff09;是一种同步串行通信协议&#xff0c;常用于连接微控制器和外围设备。SPI有四种模式&#xff0c;分别是0、1、2、3模式。 0模式&#xff1a;时钟空闲时为低电平&#xff0c;数据在时钟的下降沿采样&#…

Using sunbeam to deploy openstack (by quqi99)

作者&#xff1a;张华 发表于&#xff1a;2023-10-15 版权声明&#xff1a;可以任意转载&#xff0c;转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明(http://blog.csdn.net/quqi99) What’s sunbeam sunbeam是一个部署openstack的工具&#xff0c;它会用ju…

利用ChatGPT练习口语

目录 ChatGPT 这两天发布了一个激动人心的新功能&#xff0c;App端&#xff08;包括iOS和Android&#xff09;开始支持语音对话以及图片识别功能。 这两个功能一如既往的优先开放给Plus用户使用&#xff0c;现在将App更新到最新版本&#xff0c;就能体验。 为什么说激动人心&a…

Android组件通信——PendingIntent(二十八)

1. PendingIntent 1.1 知识点 &#xff08;1&#xff09;了解PendingIntent与Intent的区别&#xff1b; &#xff08;2&#xff09;可以完成Notification功能的开发&#xff1b; &#xff08;3&#xff09;可以使用PendingIntent进行短信的发送&#xff1b; 1.2 具体内容 …