volatile怎么保证可见性,synchronized和lock的区别,synchronized的底层实现

可见性是指:当多个线程访问同一个变量时,某个线程修改了该变量的值,其他线程可以立即看到修改后的变量。当一个共享变量被volatile修饰后,一旦该变量的值被修改,修改后的变量会被理机更新到主存中,当有其他线程需要该变量的值会到主存中读取。

(存在层次)synchronized是JVM实现的,他是java的关键字。lock是java中的接口。

(锁的释放)当出现异常的时候,synchronized会主动释放线程占用的锁,因此不会出现死锁现象。但是lock需要通过unlock( )主动释放占用的锁,因此可能会出现死锁。我们需要在final部分释放占用的锁。

(锁的获取)使用synchronized时,等待锁的线程会一直等待下去不会响应中断,但是使用Lock的线程可以响应中断。

(锁的状态)synchronized无法判断线程是否已经获取了锁;但是Lock可以。

(锁的类型)synchronized的锁是可重入、不可中断、非公平的;Lock是可重入、可中断、可公平的。

可重入指执行对象中的同步方法不用再次获得锁。公平锁指按要获取锁的线程的等待时间分配锁,等待时间越长越有获取锁的优先权。

(锁的性能)Lock可以通过readwriteblock进行读写分离,提升线程的读写效率。当资源竞争不激烈的情形下,synchronized的性能优于Lock,但是当资源竞争激烈时,Lock的性能会优于synchronized。

synchronized的底层实现

synchronized可以同步一个代码块、一个方法甚至一个类。

若synchronized同步一个代码块,它是作用于这个对象的。调用两个对象上的同步代码块是不会引起同步的。

若synchronized同步一个方法可以分为两种:一种是修饰实例方法,此时它作用于该对象;若修饰静态方法,则它作用于该类。

若synchronized同步的是一个类,此时调用同一类的不同对象就会引起同步。

synchronized的底层是基于进入和推出管程(Monitor)对象实现的。无论是显示同步(有明确的Monitorenter和Monitorexit指令)还是隐式同步都是如此。

同步一个代码块时,使用的是显示同步。Monitotenter指令指向代码的入口,Monitorexit指令指向代码块结束的地方。当一个线程企图进入代码块时,会执行Monitorenter指令,试图获取对象锁(Objectref)所对应的Monitor的所有权。若Objectref的Monitor的进入计数器为0,那么该线程会进入代码块,否则该线程等待。当该线程进入代码块时,将进入计数器置为1。若该进程已经获得Monitor的所有权,它可以重入这个Monitor,此时计数器加1。代码执行结束,会执行Monitorexit指令,让其他进程进入。需要注意的是,为了保证该方法异常时,Monitorenter和Monitorexit指令仍能正确配对执行,编译器会产生一个异常处理器,这个异常处理器声明为可以处理任何异常,目的就是为了执行Monitorexit指令。

同步一个方法时,使用的是隐式同步。此时并没有采用Monitorenter和Monitorexit指令,而是使用了ACC_SYNCHRONIZED标识符,JVM通过该标识判断一个方法是否被声明为同步方法。

Java对象在内存中的分布布局为:对象头,实例变量,填充数据。对象头中有两个主要的结构,一个是Mark Word,另一个Class Metadata Adress。在Mark Work中存储该对象的hashcode( )等重要信息,重量级锁便保存在其中,它也是synchronized的对象锁,指向一个Monitor对象的起始地址。每个对象中都有一个Monitor与之对应,当线程持有某个Monitor后,该Monitor就会被锁定。可见Monitor对象存在于每个对象的对象头中,synchronized就是通过这种方式获得对象锁的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值