同步访问共享的可变数据(66)

关键字synchronized 保证同一时刻,只有一个线程执行某一个方法或代码块安全

  • 当一个对象被一个线程修改时,能够阻止其余线程看到其内部的不一致状态
  • 正确的使用同步能够避免任何对象看到其不一致状态

不只于此,并发

  • 没有同步,各个线程之间对象的变化是相互不感知的
  • 进入的各个线程都能看到,同一个锁保护的以前全部的修改信息
    • 就是说不一样步,别的线程改变对象值,本线程不必定什么时候能看到修改后的值

Java 语言规范保证读或者写一个变量(除了long、double)是原子的性能

为了提高性能,在读写原子数据的时候,不使用同步也是很危险的优化

  • 由于一个线程写入的值,对于另外一个线程不必定是可见的
  • 为了线程之间可靠的通讯,为了互斥访问,同步是必要的

不要使用Thread.stop 方法,线程不安全线程

  • boolean是原子读写的,不须要加锁
  • 可是这段代码是不会中止的

  • 问题在于:因为没有同步,不能保证后台线程合适能看到这个boolean变量
  • 没有同步,虚拟机把代码优化成:

---->3d

  • 加上同步域,可知足一秒左右中止线程

  • 如上看到,读写方法都被同步
    • 若是读写操做没有都被同步,仅仅同步写操做,同步是不会起做用的
    • 同步仅仅为了通讯效果,由于读写是原子的

第三个版本,使用volatile 关键字:对象

  • volatile 不提供互斥访问
  • 每次写入都会写入主存,其余线程及时可见

  • 使用volitale 产生序列号,请当心::
    • 这里的 a++ 操做不是原子的,得到的结果可能会有问题

  • 能够考虑使用原子包

最佳办法:blog

  • 要么不共享可变数据,要么共享不可变数据
  • 尽可能将可变数据,限制在一个线程内 
  • 安全发布对象引用
    • 静态域、volitale、final、锁定的访问域、放到并发的集合中

当多个线程共享可变数据的时候,读和写都须要同步同步

  • 同步作了两件事:
    • 及时通知其余线程
    • 互斥访问
  • 会形成活性失败和安全性失败
  • 若是仅仅须要线程间交互通讯,不须要互斥访问:请使用volitale
相关文章
相关标签/搜索