悲观锁&乐观锁

简介: 悲观锁&乐观锁

@[toc]

锁都分类

在这里插入图片描述

什么是悲观锁,乐观锁

乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。

悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

如图所示 ,synchronized 就是悲观锁都一个实现思路,如下代码,
每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁

private Object object =new Object();
    
    public void sale(){
        synchronized (object){
            if(count > 0){
                System.out.println(Thread.currentThread().getName() +"出售 :" +(100 - count + 1));
                count--;
            }
        }
    }

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

以 java.util.concurrent 中的 AtomicInteger 为例

AtomicInteger 内部使用 cas无锁机制,不会进行加锁, 但是在更新的时候会判断一下在此期间别人有没有去更新这个数据

package com.dimple.test;

import java.util.concurrent.atomic.AtomicInteger;

public class Test5 {


    public static void main(String[] args) {

        TestDemo thread = new TestDemo();
        Thread t1 = new Thread(thread,"窗口一");
        Thread t2 = new Thread(thread,"窗口二");
        t1.start();
        t2.start();
    }
}

class TestDemo implements Runnable{
    //共享的火车票变量
    private static AtomicInteger atomic = new AtomicInteger(100);

    //重寫run方法
    @Override
    public void run() {
        while (atomic.get() > 0){
            try {
                //休眠一下 方便出现并发问题
                Thread.sleep(50);
            }catch (Exception e){
                e.getMessage();
            }

            sale();
        }
    }
    //卖票
    public void sale(){

        if(atomic.get() > 0){
          Integer count=  100 - atomic.getAndDecrement() + 1; //使用底层方法getAndDecrement()  自-1;
            System.out.println(Thread.currentThread().getName()+ "," + count);//获取当前值
        }


    }

}

经典案例

  • git 版本控制工具 典型都乐观锁实现思路,当我们往远程仓库 push的时候 ,git 会检查我们的版本是否落后于版本库的版本,如果落后,push就会报错,如果一致,就提交成功
  • git 不适用于悲观锁,否则 公司倒闭

开销对比

悲观锁的开销肯定要大于乐观锁,但是特点一劳永逸,乐观锁 始终无锁机制,比对版本号,性能要优于 悲观锁,
在这里插入图片描述

相关文章
|
定位技术
Echarts实战案例代码(10):echarts结合世界所有国家地图数据集geojson的(英文翻译映射)解决方案
Echarts实战案例代码(10):echarts结合世界所有国家地图数据集geojson的(英文翻译映射)解决方案
1324 0
Echarts实战案例代码(10):echarts结合世界所有国家地图数据集geojson的(英文翻译映射)解决方案
|
Web App开发
如何实现一个项目配置多个商户信息付款给对应商户
说明:本帖主要说明如何实现给一个平台配置多个商户的号实现多个商户收款。主要用于没有门店和第三方授权方式 支付宝最终是根据请求过来的appid来判断哪一个商户收款(也就是请求是谁的appid就收款到谁的账号下)    方案一:      1.
1584 12
|
9月前
|
Kubernetes Docker 容器
Kubernetes与Docker参数对照:理解Pod中的command、args与Dockerfile中的CMD、ENTRYPOINT。
需要明确的是,理解这些都需要对Docker和Kubernetes有一定深度的理解,才能把握二者的区别和联系。虽然它们都是容器技术的二个重要组成部分,但各有其特性和适用场景,理解它们的本质和工作方式,才能更好的使用这些工具,将各自的优点整合到生产环境中,实现软件的快速开发和部署。
357 25
|
存储 网络架构
网络速率与下载速率
【8月更文挑战第8天】
2876 1
网络速率与下载速率
|
安全 Java 开发工具
云效codeup
简要讲述云效codeup使用操作及使用感受
云效codeup
|
11月前
|
负载均衡 定位技术 网络安全
阿里云国际站注册教程:阿里云cdn加速怎样
通过阿里云CDN加速,用户可以实现网站内容的快速加载,提升用户体验,同时减轻源站服务器的压力,提高网站的访问速度和稳定性
|
11月前
|
Java jenkins 持续交付
Jenkins集成Maven
通过以上步骤,可以在Jenkins中成功集成Maven,实现自动化构建和部署。通过定时构建、SCM轮询等方式,可以确保代码库中的最新变更能够及时构建和测试,提高开发效率和代码质量。这种集成方式在实际项目中具有广泛的应用前景,能够显著提升团队的协作效率。
309 8
|
人工智能 算法 安全
探索量子计算:从基础原理到未来应用
探索量子计算:从基础原理到未来应用
|
安全 数据挖掘 API
快手小店详情API接口的获取与应用
在数字化时代,电商平台竞争激烈,API接口作为连接不同系统和服务的桥梁,已成为电商生态中不可或缺的一部分。本文详细介绍快手小店详情API接口的获取与应用,帮助开发者和企业提升业务效率和用户体验。涵盖API接口定义、主要应用场景、注册与认证流程、调用方法及实际应用案例,提供最佳实践建议。
524 1
|
机器学习/深度学习 数据挖掘
数据特征
数据特征
566 2