我所知道并发编程之synchronized保证线程安全的原理(理论、JVM)

前言


在上一篇文章中我们讲到实现了一个数值序列生成器

但是在我们的多线程的环境下,会发现生成的数值序列不是我们所预期的那种递增的序列,而是会出现那种我们所不预期的错误

当时的解决方案比较简单,就在那个方法上加了一个synchronized,于是这个问题就解决了,我们并没有去详细的解释为什么在方法上加了一个synchronized就能够解决

从本篇文章开始,我们来正式的了解解决线程安全性问题的各种的方案,首先第一个就是synchronized,我们后面还会学习其他的锁呀、包括我们的元子类等等

一、内置锁


在看synchronized之前,我们首先来看内置锁,什么是内置锁呢

就是说Java中每一个对象都可以用作同步的锁,那么这些锁就被称之为内置锁

我们使用代码体会体会内置锁是什么意思?

public class Sequence {

    int value;

    public synchronized  int getNext(){
        return  value++;
    }
    
}

我们说每一个Java中的对象都是一个内置锁,当这个线程在进入同步代码块之前,都必须先获得锁也就是获得内置锁,然后获得锁之后就可以进入到同步代码块中执行

image.png

而我们的synchronized放在方法上,也就是说实例方法普通方法上,那么内置锁也就是所谓的对象锁,就是当前类的实例

public class Sequence {


    /**
     * synchronized 放在普通方法上,默认内置锁是当前实例
     * @return
     */
    public synchronized  int getNext(){
        return  value++;
    }
    
}

而其他的线程再想进来,那么就必须等待,于是这个线程开始往下执行,我们之前也都翻译过了,value++是执行了好多的字节码指令,那么,等字节码指令执行完毕之后,这个线程就可以释放掉锁了,把它拿到的锁释放掉

image.png

这个synchronized它除了能用在方法上以外,它还能用修饰静态方法,也就是类的方法

public class Sequence {


    private static int value;

    /**
     * synchronized 放在静态方法上,内置锁是当前的Class字节码对象
     * @return
     */
    public static synchronized int getPrevious(){
        return value --;
    }
    
}

同时它除了修饰方法以外它还能够修饰代码块,我们可以举个例子使用同步代码块来修饰它

public class Sequence {


    public int getValue(){

        synchronized (Integer.valueOf(value)){
            
        }
        if(value>0){
            return value;
        }else{
            return  -1;
        }
    }
}

万物皆对象,你只要这里指定一个对象,那么,就可以作为一把锁

其实synchronized的原理其实就是加了锁,内置锁和互斥锁所决定的。每个对象都有锁,而这些锁都是互斥的,一个进来之后,另外的就不能进来了,因此就可以保证线程的安全性

二、字节码查看synchronized


那么在从字节码层面,在Java虚拟机规范中,可以看到,synchronized在Java虚拟机中执行同步代码块的时候,其实它是基于进入和退出monitor对象来实现方法同步的

image.png

我们可以观看字节码指令查看该Sequence.class的同步代码块部分

image.png

发现在第4行就是monitorenter进入执行,执行到第17行就退出

而当我们一般编写if-else时就会遇到goto,同时会跳到相应的操作并也释放锁

参考资料


龙果学院:并发编程原理与实战(叶子猿老师)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值