Java多线程(九)线程的同步

导读:本篇文章讲解 Java多线程(九)线程的同步,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、线程不安全的

点击这里了解线程并发的知识Java多线程(四)线程并发的理解

上面的案例可以看到,在并发的场景下,线程不是安全的,为了解决这个问题,我们使用线程的同步(synchronized)。

二、同步方法
  • 代码案例:
/**
 * 手机抢购案例
 */
public class PhoneSnapUp implements Runnable {

    private Integer inventory = 10;//手机库存
    private boolean flag = true;

    public static void main(String[] args) {
        PhoneSnapUp phoneSnapUp = new PhoneSnapUp();
        //模拟5人同时抢购,即同时开启5个线程
        new Thread(phoneSnapUp, "丁大大1号").start();
        new Thread(phoneSnapUp, "丁大大2号").start();
        new Thread(phoneSnapUp, "丁大大3号").start();
        new Thread(phoneSnapUp, "丁大大4号").start();
        new Thread(phoneSnapUp, "丁大大5号").start();
    }

    @Override
    public void run() {
        while (flag){
            try {
                buy();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //购票方法提出来
    private synchronized void buy() throws Exception {
        //当库存为0时,抢购结束
        if (inventory <= 0) {
            flag = false;
            return;
        }
        //模拟延迟,否则结果不容易看出来
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //每次抢购完,库存减1
        System.out.println("恭喜!!" + Thread.currentThread().getName() + "--抢到了一台小米12!库存还剩:" + --inventory + "台");
    }
}
  • 执行结果如下:
    在这里插入图片描述

  • 可以看到,并没有发生抢购错误的情况。

三、同步代码块
  • 代码案例:
/**
 * 手机抢购案例
 */
public class PhoneSnapUp implements Runnable {

    private Integer inventory = 10;//手机库存
    private boolean flag = true;

    public static void main(String[] args) {
        PhoneSnapUp phoneSnapUp = new PhoneSnapUp();
        //模拟5人同时抢购,即同时开启5个线程
        new Thread(phoneSnapUp, "丁大大1号").start();
        new Thread(phoneSnapUp, "丁大大2号").start();
        new Thread(phoneSnapUp, "丁大大3号").start();
        new Thread(phoneSnapUp, "丁大大4号").start();
        new Thread(phoneSnapUp, "丁大大5号").start();
    }

    @Override
    public void run() {
        while (flag){
            try {
                synchronized (this) {
                    buy();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //购票方法提出来
    private void buy() throws Exception {
        //当库存为0时,抢购结束
        if (inventory <= 0) {
            flag = false;
            return;
        }
        //模拟延迟,否则结果不容易看出来
        Thread.sleep(500);
        //每次抢购完,库存减1
        System.out.println("恭喜!!" + Thread.currentThread().getName() + "--抢到了一台小米12!库存还剩:" + --inventory + "台");
    }
}

  • 执行结果如下:
    在这里插入图片描述
四、总结
  • 同步代码方法是用在所需操作的方法上。
  • 同步代码块用在具体的操作上,需要加对象锁。

路漫漫其修远兮,吾必将上下求索~
如果你认为i博主写的不错!写作不易,请点赞、关注、评论给博主一个鼓励吧**转载请注明出处哦**

Java多线程扩展:Java多线程学习汇总

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/17106.html

(0)
小半的头像小半

相关推荐

极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!