Java多线程与并发 - Synchronized的使用与原理

Synchronized的使用

  • 普通同步方法:锁是当前实例对象
    //锁住的是当前类实例
    public synchronized int getNext(){
        return value++;
    }
  • 静态同步方法:锁是当前类的Class对象
//锁住的时当前Class对象
public synchronized static int getNext(){
        return value++;
    }
  • 同步方法块:锁是Synchronized括号里配置的对象
    //这里可以锁住任何对象。原因来自原理。
    public  int getNext(){
        synchronized(this){
            return value++;
        }
    }

理解Synchronized的原理

  • 总的来说是通过对锁对象关联的monitor的取用与释放来实现的。因此Sychroniezd也叫做内置锁。
    关于monitor(理解为一个有监视作用的互斥量):http://blog.csdn.net/b9x__/article/details/79274672

  • java中任何一个对象都一个monitor与之关联(潜在关联),当且一个monitor被持有后,它将处于锁定状态,每一个被锁住的对象都会和一个monitor record(线程私有的数据结构)关联。Synchronized(对象)就是获取对象的monitor,synchronized下的代码就意味着放入了monitor监视区域,monitor record中中有一个Owner字段存放拥有该锁的线程的唯一标识,表示该锁被这个线程占用,这时就可以执行monitor监视区域的代码了,这些JVM在后台会自动实现。也就是Synchronized在JVM里的实现都是基于进入和退出Monitor对象来实现方法同步和代码块同步,虽然具体实现细节不一样,但是都可以通过成对的MonitorEnter和MonitorExit指令来实现。MonitorEnter指令插入在同步代码块的开始位置,当代码执行到该指令时,将会尝试获取该对象Monitor的所有权,即尝试获得该对象的锁,对象的锁存放在对象头的标志位Mark Word中(这里还有偏向锁,轻量级锁,自旋锁,Sychronized这个是重量级锁),自然monitorExit指令则插入在方法结束或异常处。

    i++字节码指令:
    这里写图片描述

  • 每一个被锁住的对象和一个monitor record关联是通过对象头的MarkWord中的LockWord指向monitor record的起始地址来关联的。

  • 任何一个对象都一个monitor与之关联,而Synchronized又是通过对锁对象关联的monitor的取用与释放来实现的,所以在同步方法块中Synchronized锁住的可以是任何对象。

抛开细节理解:每个对象都有monitor,Synchronized(对象)就是获取对象的monitor,获取到的就可以进去同步块执行(字节码指令monitorenter),执行完后释放对象的monitor(字节码指令monitorexit),这是其他线程才可获取对象的monitor。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值