1. 悲观互斥

互斥实际是悲观锁的思想

例如,有下面取款的需求

interface Account {
   // 获取余额
   Integer getBalance();

   // 取款
   void withdraw(Integer amount);

   /**
    * 方法内会启动 1000 个线程,每个线程做 -10 元 的操作
    * 如果初始余额为 10000 那么正确的结果应当是 0
    */
   static void demo(Account account) {
       List<Thread> ts = new ArrayList<>();
       for (int i = 0; i < 1000; i++) {
           ts.add(new Thread(() -> {
               account.withdraw(10);
          }));
      }
       long start = System.nanoTime();
       ts.forEach(Thread::start);
       ts.forEach(t -> {
           try {
               t.join();
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      });
       long end = System.nanoTime();
       System.out.println(account.getBalance()
               + " cost: " + (end-start)/1000_000 + " ms");
  }
}

用互斥来保护

class AccountSync implements Account {

   private Integer balance;

   public AccountUnsafe(Integer balance) {
       this.balance = balance;
  }

   @Override
   public Integer getBalance() {
       synchronized (this) {
           return this.balance;
      }
  }

   @Override
   public void withdraw(Integer amount) {
       synchronized (this) {
           this.balance -= amount;
      }
  }
}

2. 乐观重试

另外一种是乐观锁思想,它其实不是互斥

class AccountCas implements Account {
   private AtomicInteger balance;

   public AccountCas(int balance) {
       this.balance = new AtomicInteger(balance);
  }

   @Override
   public Integer getBalance() {
       return balance.get();
  }

   @Override
   public void withdraw(Integer amount) {
       while(true) {
           // 获取余额的最新值
           int prev = balance.get();
           // 要修改的余额
           int next = prev - amount;
           // 真正修改
           if(balance.compareAndSet(prev, next)) {
               break;
          }
      }
  }
}



Java并发(十四)----悲观互斥与乐观重试的更多相关文章

  1. “全栈2019”Java第九十四章:局部内部类详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  2. “全栈2019”Java第十四章:二进制、八进制、十六进制

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  3. “全栈2019”Java第二十四章:流程控制语句中决策语句switch下篇

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  4. Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...

  5. Java中的锁-悲观锁、乐观锁,公平锁、非公平锁,互斥锁、读写锁

    总览图 如果文中内容有错误,欢迎指出,谢谢. 悲观锁.乐观锁 悲观锁.乐观锁使用场景是针对数据库操作来说的,是一种锁机制. 悲观锁(Pessimistic Lock):顾名思义,就是很悲观,每次去拿数 ...

  6. Elasticsearch由浅入深(四)ES并发冲突、悲观锁与乐观锁、_version乐观锁并发

    ES并发冲突 举个例子,比如是电商场景下,假设说,我们有个程序,工作的流程是这样子的: 读取商品信息(包含了商品库存) 用户下单购买 更新商品信息(主要是将库存减1) 我们比如咱们的程序就是多线程的, ...

  7. 【Java并发编程四】关卡

    一.什么是关卡? 关卡类似于闭锁,它们都能阻塞一组线程,直到某些事件发生. 关卡和闭锁关键的不同在于,所有线程必须同时到达关卡点,才能继续处理.闭锁等待的是事件,关卡等待的是其他线程. 二.Cycli ...

  8. Java 并发编程(四):如何保证对象的线程安全性

    01.前言 先让我吐一句肺腑之言吧,不说出来会憋出内伤的.<Java 并发编程实战>这本书太特么枯燥了,尽管它被奉为并发编程当中的经典之作,但我还是忍不住.因为第四章"对象的组合 ...

  9. 【JAVA并发第四篇】线程安全

    1.线程安全 多个线程对同一个共享变量进行读写操作时可能产生不可预见的结果,这就是线程安全问题. 线程安全的核心点就是共享变量,只有在共享变量的情况下才会有线程安全问题.这里说的共享变量,是指多个线程 ...

  10. [转]Java并发的四种风味:Thread、Executor、ForkJoin和Actor

    这篇文章讨论了Java应用中并行处理的多种方法.从自己管理Java线程,到各种更好几的解决方法,Executor服务.ForkJoin 框架以及计算中的Actor模型. Java并发编程的4种风格:T ...

随机推荐

  1. iview 将Modal抽取成组件并控制Modal的显示隐藏

    开发中遇到Modal弹出框的内容太多,就想把Modal单独分装成一个组件,但是发现封装成组件后Modal的关闭和打开有问题.如下方法可以解决这个问题. 父级页面: <PriceInfodModa ...

  2. 编写Java代码时应该避免的6个坑

    通常情况下,我们都希望我们的代码是高效和兼容的,但是实际情况下代码中常常含有一些隐藏的坑,只有等出现异常时我们才会去解决它.本文是一篇比较简短的文章,列出了开发人员在编写 Java 程序时常犯的错误, ...

  3. Linux环境下如何查看Python版本号

    方法一.直接执行命令python,就可以查看python的版本信息. 退出用exit() 方法二.利用命令python -V,注意V要大写. 方法三.利用命令whereis python,注意wher ...

  4. 图的遍历(DFS和BFS)

    声明:图片及内容基于https://www.bilibili.com/video/BV1rp4y1Q72r?from=articleDetail 图的遍历 深度优先遍历(DFS) DFS核心是递归和栈 ...

  5. Angular系列教程之父子组件通信详解

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  6. DataGrip连接MySql数据库失败:dataGrip java.net.ConnectException: Connection refused: connect.

    1.问题 报错:dataGrip java.net.ConnectException: Connection refused: connect. 详细错误:[08S01] Communications ...

  7. c# 创建一个只接收消息的窗口

    /// <summary> /// WM_COPYDATA消息,进程间传输信息专用结构 /// </summary> public struct COPYDATASTRUCT ...

  8. 第二章 VB.NET 绘图基础

    GDI+( Graphics Device Interface Plus)是 Windows操作系统用来执行绘画及其他相关图形操作的一套子系统,是由. Net Framework中的System.Dr ...

  9. [转帖]nginx反向代理时保持长连接

    https://www.cnblogs.com/liufarui/p/11075630.html ·[场景描述] HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上 ...

  10. [转帖]TLS1.3 正式版发布 — 特性与开启方式科普

    https://cloud.tencent.com/developer/article/1376033 互联网工程指导委员会(IETF)释出了传输层安全性协议的最新版本 TLS 1.3.TLS 被广泛 ...