自学内容网 自学内容网

线程安全(二)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) {
   
    

原文地址:https://blog.csdn.net/qq_33204709/article/details/140349497

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!