淺談synchronized

淺談synchronized

前言

看多線程的相關書籍的時候,會常常閱讀到一個使用前景,就是銀行的取錢存錢操做。
假設咱們使用兩個線程來模擬取錢操做,模擬兩我的使用同一個帳戶併發取錢的問題,咱們都知道存款不可能爲負的,
可是每每併發操做的時候,可能就會致使系統出錯致使出現負的數字(假設一開始都是200元餘額,兩邊同時操做取出150,系統可能就會出錯)。
出現相似這種問題就是缺乏同步安全性,爲了解決這個問題,Java就增進了同步監視器來解決這個,也就是本文講的synchronized的做用。安全

是什麼

synchronized是Java中的關鍵字。同步的意思,用在解決線程安全問題上。有添加在方法上,和直接修飾代碼塊。有種保護的做用,使用修飾以後,家門上了鎖,別人進不來。用synchronized修飾的方法只容許一個線程執行,其餘線程沒法進入該方法。(原子性操做),銀行使用該操做以後,就會變成一個排隊操做同樣,像前言的例子,就會變成一我的等另外一個操做取出150以後才能夠取錢,這樣就不會出現負的餘額。多線程

  1. 基本上全部的併發模式 在解決線程衝突的時候,都是採用序列化訪問共享資源的方案。就是在給定的時間間隔內只容許一個任務訪問共享資源。
因此synchronized保護的是線程遭受破壞,必須按照容許的權限進行資源訪問。

記得synchronized關鍵字能夠修飾方法,能夠修飾代碼塊,但不能修飾構造函數、屬性等。併發

//long與double的操做不是原子的

格式

同步代碼塊

//synchronized代碼塊
//obj對象即表示線程開始執行同步代碼塊以前,必須先得到對同步監視器的鎖定
//步驟:加鎖--修改--釋放鎖
synchronized (obj) {
    ...
}

任什麼時候刻只能有一個線程能夠得到對同步監視器的鎖定,當同步代碼塊執行完成後,該線程會釋放對該同步監視器的鎖定。具體的格式參見上面。函數

同步方法

//synchronized方法,能夠分爲靜態方法和普通方法
synchronized void method(){
    ...
}
//等價於
public void method()
{
   synchronized(this) {
      // todo
   }
}
//不管哪一種形式均可以看作是「{」處獲取鎖,「}」釋放鎖

與同步代碼塊對應,Java 的多線程安全支持還提供了同步方法,同步方法就是使用synchronized關鍵字來修飾某個方法(放在權限詞的後面便可),則該方法稱爲同步方法。對於同步方法而言,無須顯式指定同步監視器,同步方法的同步監視器是this,也就是該對象自己。在格式上能夠看到一些用法,可是具體來說,synchronized用在方法體上還分爲用在普通方法和靜態方法兩種,區別在做用鎖對象的不一樣。工具

修飾普通方法做用的是調用這個方法的對象,修飾靜態方法做用是調用這個類的全部對象。
synchronized static方法能夠在類的範圍內防止對static數據的併發訪問,

使用同步方法能夠很方便得實現線程安全的類,這樣類的對象能夠被多個線程同時安全得訪問。學習

注意

  1. synchronized不能被繼承。
  2. collection中的線程不安全的集合能夠變成使用Collections工具類的,具體用法語句能夠參考API文檔,寫的還算比較詳細。

最後

  1. 關於什麼使用同步,也就是上鎖,引用書上的話this

    若是你在寫一個變量,它可能接下來將被另外一個線程讀取,或者正在讀取上一個已經被另外一個線程寫過的變量,那麼你必須使用同步,而且,讀取線程都必須用相同的監視器鎖同步線程

    ​ ——Brain Goetz《Java Concurrency in Pactice》的做者code

  2. 我的學習記錄,有錯誤歡迎指點,謝謝!加油!

相關文章
相關標籤/搜索