首页 > 编程语言 > 详细

线程同步问题以及synchronized的引入

时间:2020-09-05 23:16:54      阅读:62      评论:0      收藏:0      [点我收藏+]

线程同步问题以及synchronized的引入

我们之前写了个模拟银行排队叫号的demo,这里为了说明问题我把代码稍加改造:

public class TicketWindowRunnable implements Runnable {
    private int index = 1;
    private static final int MAX = 500;

    @Override
    public void run() {
        while (true) {
            if (index >= MAX)
                break;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 的号码是:" + (index++));

        }
    }
}

运行效果如下:
技术分享图片

可以看到我们的运行结果竟然出现了501,其实这个是因为线程同步问题导致的,这在我们并发中经常提到,类似的比如商品超卖等都并发中同时读了数据,然后做了操作。我们来引入synchronized试一下:

public class TicketWindowRunnable implements Runnable {
    private int index = 1;
    private static final int MAX = 500;
    private final Object MOINTOR = new Object();
    @Override
    public void run() {
        while (true) {
            synchronized (MOINTOR){
                if (index >= MAX)
                    break;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 的号码是:" + (index++));
            }
        }
    }
}

运行效果如下:
技术分享图片

synchronized 它可以把任意一个非 NULL 的对象当作锁。他属于独占式的悲观锁,同时属于可重

入锁。

Synchronized 作用范围

  1. 作用于方法时,锁住的是对象的实例(this);

  2. 当作用于静态方法时,锁住的是Class实例,又因为Class的相关数据存储在永久带PermGen(jdk1.8 则是 metaspace),永久带是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程;

  3. synchronized 作用于一个对象实例时,锁住的是所有以该对象为锁的代码块。它有多个队列。

    更多细节我们后续再学习。

线程同步问题以及synchronized的引入

原文:https://www.cnblogs.com/stormsquirrel/p/13619052.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!