Java同步机制

看之前可以先看下java内存模型(http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html),可以更好理解本文

一、volatile

关键字volatile可以说是Java提供的最轻量级的同步机制,但是他并不容易完全被正确、完整地理解,以至于许多人都不去使用他。

当一个变量定义为volatile之后,他将具有两种特性,第一是保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。而普通变量不能做到这一点,普通变量的值在线程间传递需要通过主内存来完成,例如,线程A修改了一个普通变量的值,然后向主内存进行回写,另一条线程B在线程A回写完成了之后再从主内存进行读取操作,新变量值才会对线程B可见。

当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。

另外,通过synchronized和Lock也能够保证可见性,synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。

volatile变量对所有线程是立即可见的,对volatile变量 所有的写操作都能立刻反应到其他线程当中,换句话说,volatile变量在各个线程中是一致的。当并不能得出“基于volatile变量的运算在并发下是安全的“这个结论。volatile变量在各个线程的工作内存中不存在一致性问题,但是Java里面的运算并非原子操作,导致volatile变量的运算在并发下一样是不安全的。

由于volatile变量只能保证可见性,在不符合以下两条规则的运算场景中,我们仍然要通过加锁来保证原子性。

  • 运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
  • 变量不需要与其他的状态变量共同参与不变约束。
volatile变量的第二个特性是禁止指令重排序优化,普通的变量仅仅会保证在该方法的执行过程中所有依赖赋值结果的地方都能获取正确的结果,而不能保证变量赋值操作的顺序与程序代码中的执行顺序一致。
Java内存模型要求lock、unlock、read、load、use、assign、store、write这8个操作都具有原子性,但对于64位的数据类型(long和double),虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位的读写操作来进行,即允许虚拟机实现选择可以部保证64位数据类型的read、load、store、write这4个操作的原子性。
二、synchronized
为了解决线程中的同步问题Java多线程引入了同步监视器来解决这个问题,使用同步监视器的代码块就是同步代码块。
synchronized可以修饰对象或方法格式如下:
synchronized(obj){//将obj对象锁定
     //此处的代码块就是同步代码块
}

public synchronized void fun(){
    //同步代码块
}
不管synchronized修饰的是方法还是对象,它始终锁定的是对象的实例变量,或者类变量。当执行同步代码块时,就会先获取该对象的同步监视器的锁,直到线程执行完同步代码块之后才会释放对同步监视器的锁定。
当进入一个同步代码块得到对象锁后,会从主内存中加载该对象 ,所以在锁定区域代码开始执行之前,持有锁的线程就和锁定对象主内存中的视图同步了。
synchronized代码块或方法执行完成之后,对被锁住的对象所做的任何修改全部都会在对象锁释放前刷回到主内存中。
使用synchronized关键字实现的同步代码块有一些缺点:锁只有一种类型,得不到锁就会被阻塞,并发性能较差。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值