synchronized关键字

我们在使用多线程的时候,会遇到多个线程抢占同一资源问题,比如在厕所了里有三个坑位,小明内急进了第一个坑位上厕所,没关门没上锁,小红也有内急也来到了第一个坑位,推门而入,进去发现小明也在,那就尴尬了。
为了解决这种问题,于是有了我们的synchronized关键字同步代码块,废话不多说看代码。

public class Race implements Runnable {
    /**
     * 定义一个总坑位
     */
    private int ticket = 10;
    /**
     * 抛出Thread.sleep的异常
     */
    @SneakyThrows
    @Override
    public void run() {
        while (true) {
            if (ticket <= 0) {
                break;
            }
            // 因为线程太快沉睡200ms
            Thread.sleep(100);
            // 打印第几张票
            System.out.println(Thread.currentThread().getName() + "拿到了第" + ticket-- + "坑位");
        }
    }
    public static void main(String[] args) {
        // 创建对象
        Race race = new Race();
        // 放入对象,并给线程命名
        new Thread(race, "李同学").start();
        new Thread(race, "张同学").start();
        new Thread(race, "老师").start();
    }
}

以下是运行结果,其中张同学跟李同学都占了第七坑位,出现了我们上面遇到了尴尬情况,那怎么解决这种问题呢,就使用到了我们的synchronized关键字

在这里插入图片描述

我们使用synchronized关键字 先看代码

1. 第一种用同步代码块方式

public class Race implements Runnable {
    /**
     * 定义一个总坑位
     */
    private int ticket = 10;

    Object obj = new Object();
    /**
     * 抛出Thread.sleep的异常
     */
    @SneakyThrows
    @Override
    public void run() {
        while (true) {
        synchronized (obj){
                if (ticket <= 0) {
                    break;
                }
                // 因为线程太快沉睡200ms
                Thread.sleep(100);
                // 打印第几张票
                System.out.println(Thread.currentThread().getName() + "拿到了第" + ticket-- + "坑位");
            }
        }
    }
    public static void main(String[] args) {
        // 创建对象
        Race race = new Race();
        // 放入对象,并给线程命名
        new Thread(race, "李同学").start();
        new Thread(race, "张同学").start();
        new Thread(race, "老师").start();
    }
}

上面我们加入了synchronized关键字,括号内为任意对象锁,我们上面使用的是Object obj = new Object(); 的obj对象, 也可以使用 String str =""的str,任意对象锁都可以。看结果
在这里插入图片描述
加上我们的synchronized关键字 就不会出现两个同学去一个坑位的问题了。

1. 第二种用同步方法方式

public class Race implements Runnable {
    /**
     * 定义一个总坑位
     */
    private int ticket = 10;

    /**
     * 抛出Thread.sleep的异常
     */
    @SneakyThrows
    @Override
    public void run() {
        while (true) {
            if (this.method()) {
                break;
            }
        }
    }

    public synchronized Boolean method() {
        if (ticket > 0) {
            System.out.println(Thread.currentThread().getName() + "拿到了第" + ticket-- + "票");
        } else {
            return ticket > 0;
        }
        return false;
    }
    public static void main(String[] args) {
        // 创建对象
        Race race = new Race();
        // 放入对象,并给线程命名
        new Thread(race, "李同学").start();
        new Thread(race, "张同学").start();
        new Thread(race, "老师").start();
    }

}

在这里插入图片描述

以上

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值