同步訪問共享的可變數據(66)

關鍵字synchronized 保證同一時刻,只有一個線程執行某一個方法或代碼塊安全

  • 當一個對象被一個線程修改時,能夠阻止其餘線程看到其內部的不一致狀態
  • 正確的使用同步能夠避免任何對象看到其不一致狀態

不只於此,併發

  • 沒有同步,各個線程之間對象的變化是相互不感知的
  • 進入的各個線程都能看到,同一個鎖保護的以前全部的修改信息
    • 就是說不一樣步,別的線程改變對象值,本線程不必定什麼時候能看到修改後的值

Java 語言規範保證讀或者寫一個變量(除了long、double)是原子的性能

爲了提高性能,在讀寫原子數據的時候,不使用同步也是很危險的優化

  • 由於一個線程寫入的值,對於另外一個線程不必定是可見的
  • 爲了線程之間可靠的通訊,爲了互斥訪問,同步是必要的

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

  • boolean是原子讀寫的,不須要加鎖
  • 可是這段代碼是不會中止的

  • 問題在於:因爲沒有同步,不能保證後臺線程合適能看到這個boolean變量
  • 沒有同步,虛擬機把代碼優化成:

---->3d

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

  • 如上看到,讀寫方法都被同步
    • 若是讀寫操做沒有都被同步,僅僅同步寫操做,同步是不會起做用的
    • 同步僅僅爲了通訊效果,由於讀寫是原子的

第三個版本,使用volatile 關鍵字:對象

  • volatile 不提供互斥訪問
  • 每次寫入都會寫入主存,其餘線程及時可見

  • 使用volitale 產生序列號,請當心::
    • 這裏的 a++ 操做不是原子的,得到的結果可能會有問題

  • 能夠考慮使用原子包

最佳辦法:blog

  • 要麼不共享可變數據,要麼共享不可變數據
  • 儘可能將可變數據,限制在一個線程內 
  • 安全發佈對象引用
    • 靜態域、volitale、final、鎖定的訪問域、放到併發的集合中

當多個線程共享可變數據的時候,讀和寫都須要同步同步

  • 同步作了兩件事:
    • 及時通知其餘線程
    • 互斥訪問
  • 會形成活性失敗和安全性失敗
  • 若是僅僅須要線程間交互通訊,不須要互斥訪問:請使用volitale
相關文章
相關標籤/搜索