一.多线程基本篇-1.8 数据同步的引入与Synchronized的简单介绍

一.synchronized的简单介绍

public class TicketWindowRunnable implements Runnable {

    private int index = 1;

    private final static int MAX = 500;

    private final Object MONITOR = new Object();

    @Override
    public void run() {

        while (true) {
            //1
            synchronized (MONITOR) {
                if (index > MAX)
                    break;
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + " 的号码是:" + (index++));
            }
            //2
        }
    }
}

1.从上面代码,可以了解到多个线程同时执行,不会发生超卖的现象,即index最终值不会超过MAX。
2.为什么会保证不会发生超卖的现象,因为synchronized,多个线程会竞争 MONITOR锁,拿到MONITOR锁的线程才有资格执行同步代码块里的代码,当持有 MONITOR锁执行完后,会放弃 MONITOR锁,其他线程才有资格再次竞争MONITOR锁
3.synchronized里代码块,会使index++的修改对其他线程可见,这里你需要了解JMM

二.理解synchronized运行机制

  • 当一个线程竞争到 MONITOR锁时,其他线程进入某个队列中,待同步代码块执行完后,MONITOR锁会释放,队列中的线程可再次竞争

  • 从线程状态来说,等待某个线程释放MONITOR锁的线程,状态为BLOCKED,进入阻塞队列
    (1)使用jconsole可以了解到
    在这里插入图片描述
    (2)使用jstack
    在这里插入图片描述

    • 从字节码的角度,MONITOR锁实现机制是moinitorenter和monitorexit
      在这里插入图片描述

三.synchronized应用场景

  • 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁

  • 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁

  • 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁

  • this锁和class锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值