线程再学习

变量clkID和clockTime存储于主内存(main memory)内。但Java语言允许线程保存这些变量的私有专用副本(private working copy),这样可以便我们的两个线程更高效地运行。当线程读写这些变量时,它们操作的是private working copy,而非main memory中的正本。private working copy只在特定的同步点(synchronization point)才与main memory的正本进行一致化动作

 

 

对于synchronized锁包围的“代码所访问到的field”在进入,或者离开这块区域时,会强制private working copy—main memory一致化数据。

 

volatile类型的field,代码可以并发执行,并且保证private working copy和main memory是一致的。这种一致化动作是在每次访问这个变量的时候发生

 

记住,一旦变量被声明为volatile,在每次访问它们时,它们就与主内存进行一致化。但如果使用synchronized,只有在取得lock和释放lock时,才会对变量和主内存进行一致化

 

 

 

下面是的SerialNumberGenerator.nextSerialNumber()函数的字节码

Java递增操作不是atomic的,其涉及到一个读操作(getstatic)和一个写操作(putstatic),所以,即便是在这么简单的操作中,也为多线程问题留下来了空间。正如你所看到的,volatile在这里实际上不是什么问题,正在的问题在于nextSerialNumber()在没有synchronized的情况下对共享可变值进行了访问

 

如果将一个field定义为volatile,那么它就会告诉编译器不要执行任何移除读取和写入操作的优化,这么操作的目的是用线程的private working copy来维护对main memory的精确同步(1、practical java说“会在访问这个变量时来进行private working copy和main memory的一致化动作” 2、TIJ说“实际上,读取和写入操作都是直接针对内存的”)。

 

但是volatile并不能对递增不是atomic操作这一事实产生影响

 

synchronized有两个作用

1、为了互斥

2、为了通信(其实就是使得private working copy和main memory进行一致化动作)

而为了互斥的例子,我们见过很多,下面我们看个为了通信的例子

这里,每一个被同步的方法中的动作都是atomic的,使用同步的唯一目的是:为了通信而不是为了互斥访问

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值