【Java基础】- 并发 - synchronized

目录

synchronized是什么?

synchronized干什么?

底层实现原理

使用方式



version:jdk1.8


synchronized是什么?

  • Java中通过关键字实现的锁的方式
  • 通过对象头中的后三位标记,无锁,偏向锁,轻量级锁(自旋锁),重量级锁

synchronized干什么?

  • 原子性:确保线程互斥的访问同步代码;
  • 可见性:保证共享变量的修改能够及时可见,其实是通过Java内存模型中的 “对一个变量unlock 操作之前,必须要同步到主内存中;如果对一个变量进行lock操作,则将会清空工作内存中此变量的值,在执行引擎使用此变量前,需要重新从主内存中load操作或assign操作初始化变量值” 来保证的;

底层实现原理

        synchronized 同步代码块的实现是通过 monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。当执行 monitorenter 指令时,线程试图获取锁也就是获取 monitor(monitor对象存在于每个Java对象的对象头中, synchronized 锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因) 的持有权。

        其内部包含一个计数器,当计数器为0则可以成功获取,获取后将锁计数器设为1也就是加1。相应的在 执行 monitorexit 指令后,将锁计数器设为0 ,表明锁被释放。如果获取对象锁失败,那当前线程就要阻塞等待,直到锁被另外一个线程释放为止

        synchronized 修饰的方法并没有 monitorenter 指令和 monitorexit 指令,取得代之的确实是ACC_SYNCHRONIZED 标识,该标识指明了该方法是一个同步方法,JVM 通过该 ACC_SYNCHRONIZED 访问标志来辨别一个方法是否声明为同步方法,从而执行相应的同步调用。

使用方式

  • 类锁

1.类加在静态方法上

2.代码块锁Object.class

  • 对象锁

1.代码块锁

2.锁 this

class SyncStaticClazz {

    /**
     * 类锁
     *
     * 静态方法使用synchronized加锁,锁住的是当前类对象  SyncStaticClazz.class
     */
    public static synchronized void method1(){
        System.out.println("----method1----"+Thread.currentThread());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 对象锁
     *
     * 方法使用synchronized加锁,锁住的是当前类对象  new SyncStaticClazz()对象
     */
    public synchronized void method2(){
        System.out.println(" ----method2----"+Thread.currentThread());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 类锁
     *
     * 使用synchronized加锁,锁住的是SyncStaticClazz.class对象
     */
    public  void method3() {
        synchronized (SyncStaticClazz.class) {
            System.out.println("----method3----" + Thread.currentThread());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 对象锁
     *
     * 使用synchronized加锁,锁住的是new Object()对象
     */
    public  void method4() {
        Object o = new Object();
        synchronized (o) {
            System.out.println("----method4----" + Thread.currentThread());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}


个人基于源码分析,学习总结分享,如有问题,请联系博主,蟹蟹!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

debug ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值