synchronize、volatile与lock区别


一、Synchroniezd

jvm中对象放在堆内存中的,对象大致可以分为三个部分,分别是对象头,实例变量和填充字节
对象头,主要包括两部分1. Mark Word (标记字段),2.Klass Pointer(类型指针)。Klass Point 是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例(即指向方法区类的模版信息)。Mark Word用于存储对象自身的运行时数据
实例变量,存放类的属性数据信息,包括父类的属性信息,这部分内存按4字节对齐

1.使用场景

   1.修饰实例方法
   2.修饰静态方法
   3.修饰代码块

2.锁升级

	在java1.6之后Synchroniezd引入猎人偏向锁和轻量级锁
	升级过程 无锁→偏向锁→轻量级锁→重量级锁
	过程:
	偏向锁升级:
	当线程1访问加锁代码块时,偏向锁进行记录threadID。当线程2进入时判断是否为线程1,
	若为线程1则无需进入轻量级锁,若不为线程1则判断1是否存活若线程1不存活则对锁进行释放,进入无锁状态,将线程2设为偏向锁。
	若线程1存活则释放线程1,则暂停线程2,将线程1升级为轻量级锁。
	轻量级锁升级:
	线程1获取轻量级锁时,若线程2也进行获取,此时线程2发现对象头已被线程1更改,cas失败。
	线程2进行自旋等待线程1的释放,此时若线程2的自旋次数达到最大,线程1未被释放或正在执行,线程3此时进入轻量级锁。线程2进行膨胀变为重量级锁。
	*锁的升级是不可降行为

锁升级图

2.特性

	1.有序性
	2.可见性:内存强制刷新
	3.原子性:单一线程持有
	4.可重入性
	5.不可中断性

二、Volatile

1.使用场景

		某个属性被多个线程共享,其中有一个线程修改了此属性,其他线程可以立即得到修改后的值,比如booleanflag;或者作为触发器,实现轻量级同步。

2.如何保证安全性

	在单例双重检查中实现可见性和禁止指令重排序

3.与Synchronize的区别

	volatile只能修饰实例变量和类变量,而synchronized可以修饰方法,以及代码块。
	volatile保证数据的可见性,但是不保证原子性(多线程进行写操作,不保证线程安全);而synchronized是一种排他(互斥)的机制。
	volatile用于禁止指令重排序:可以解决单例双重检查对象初始化代码执行乱序问题。
	volatile可以看做是轻量版的synchronized,volatile不保证原子性,但是如果是对一个共享变量进行多个线程的赋值,而没有其他的操作,
	那么就可以用volatile来代替synchronized,因为赋值本身是有原子性的,而volatile又保证了可见性,所以就可以保证线程安全了。

三、与Lock区别

     1.synchronize是有jvm提供,lock由jdk提供具有丰富的api
     2.synchronize为自动释放锁,lock为手动释放锁
     3.synchronize为不可中断,lock可中断也可不中断
     4.lock可知道线程是否有锁,synchronize不能
     5.synchronize可锁代码块和方法,lock不能
     6.lock可使用读锁提高多线程效率
     7.synchronize非公平锁,lock可为公平锁也可不为公平锁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值