线程安全(二)synchronized 的底层实现原理、锁升级、对象的内存结构

一、基础使用

  • 假如有这样一个场景:20个用户一起抢10张票

1.1 不加锁的代码实现

public class TicketDemo {
   

    // 票总数
    private int ticketNum = 10;

    /**
     * 抢票
     */
    public void getTicket() {
   
        if (ticketNum <= 0) {
   
            return;
        }
        System.out.println(Thread.currentThread().getName() + " 抢到一张票,剩余:" + ticketNum);
        // 非原子性操作
        ticketNum--;
    }

    /**
     * 测试:20个人抢一张票
     */
    public static void main(String[] args) {
   
        TicketDemo ticketDemo = new TicketDemo();
        for (int i = 0; i < 20; i++) {
   
            new Thread(ticketDemo::getTicket).start();
        }
    }
}

执行结果:

可以看到出现了 超卖问题,一共10张票,当20个线程一起抢票就出现有11个人抢到了票。这是因为如果两个线程同时通过了 if 校验。

所以我们需要对票数的操作进行加锁,保证同一时间只有一个线程来检查和操作票数扣减。

1.2 加锁的代码实现

public class TicketDemo {
   

    // 锁
    private static Object lock = new Object();

    // 票总数
    private int ticketNum = 10;

    /**
     * 抢票
     */
    public void getTicket() {
   
        synchronized (lock) {
   
            if 

相关推荐

  1. 线(策略, synchronized 对应策略)

    2024-07-16 08:42:02       41 阅读
  2. synchronized底层和释放原理

    2024-07-16 08:42:02       30 阅读
  3. Synchronized升级过程

    2024-07-16 08:42:02       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 08:42:02       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 08:42:02       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 08:42:02       62 阅读
  4. Python语言-面向对象

    2024-07-16 08:42:02       72 阅读

热门阅读

  1. C# 继承

    2024-07-16 08:42:02       30 阅读
  2. 设计模式-三大分类

    2024-07-16 08:42:02       19 阅读
  3. JVM常见面试题2

    2024-07-16 08:42:02       24 阅读
  4. GitHub热门开源项目-2024版

    2024-07-16 08:42:02       27 阅读
  5. 浅谈微服务

    2024-07-16 08:42:02       20 阅读
  6. 深入理解MySQL中的MyISAM与InnoDB存储引擎

    2024-07-16 08:42:02       22 阅读
  7. 值的注意React中的一些默认行为和优化(一)

    2024-07-16 08:42:02       23 阅读
  8. 【机器学习】马尔可夫模型与隐马尔科夫模型

    2024-07-16 08:42:02       18 阅读
  9. 如何快速学习 Oracle 数据库?

    2024-07-16 08:42:02       19 阅读
  10. uniapp 截取两条数据 进行页面翻页滚动

    2024-07-16 08:42:02       24 阅读
  11. 【Git 学习笔记】第六章 从仓库中提取有用信息

    2024-07-16 08:42:02       28 阅读