日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java线程同步——竞争条件的荔枝+锁对象

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java线程同步——竞争条件的荔枝+锁对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【0】README

0.1) 本文描述轉自 core java volume 1, 源代碼為原創,旨在理解 java線程同步——競爭條件的荔枝+鎖對象 的相關知識;
0.2) for full source code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter14/ThreadFive.java


【1】競爭條件的荔枝

1.1)某銀行有若干個賬戶(我們這里設置為4個),且初始余額均為10000; 賬戶間存在著轉賬操作;
Attention):在模擬這個程序的過程中, 不清楚在某一時刻某銀行的賬戶轉賬多少錢,但是其總金額應該是不變的, 因為我們所做的一切不過是從銀行的一個賬戶轉賬到另一個賬戶(干貨——無論怎樣轉賬,總金額應該是不變的,始終為40000)。

對上述運行結果的分析(Analysis):

  • A1)問題在于這不是一個原子操作, 該指令可能被如下處理:
    • step1)將 account[to] 加載到寄存器;
    • step2)增加 amount 到 account[to]上;
    • step3)將結果寫回 account[to];
  • A2)現在線程1 執行step1 + step2, 然后CPU切換到執行線程2;
    • A2.1)假設線程2修改了account[to]的值;
    • A2.2)之后,線程1被喚醒,然后進行 step3;
  • A3)那顯然, 線程1的step3操作重寫了 線程2的寫入結果(線程1擦除線程2所做的更新), 所以就出現了最終的總金額不等于 40000的錯誤結果;
  • A4)如果要保持結果的合理性,只需要達到一個目的,就是將對賬戶余額的訪問加以限制,每次只能有一個線程在訪問。這樣就能保證賬戶中余額數據的合理性了。

1.2)解決方法:

  • 1.2.1)使用同步塊(synchronized):在使用同步代碼塊時候,應該指定在哪個對象上同步,也就是說要獲取哪個對象的鎖。例如:(干貨——無論怎樣轉賬,總金額應該是不變的,始終為40000)。
  • 1.2.2)使用同步方法:(干貨——無論怎樣轉賬,總金額應該是不變的,始終為40000)。

【2】鎖對象

2.1)有兩種方法防止代碼塊受并發訪問的干擾:

  • 2.1.1) synchronized 關鍵字, 構造同步塊,或是同步方法;(如1.2中解決方法 所示)
  • 2.1.2) java 5.0 引入的 ReentrantLock 類;

2.2)用ReentrantLock保護代碼塊的基本結構

myLock.lock() try {} finally {myLock.unlock() }
  • 2.2.1)這一結構確保了 任何時刻只有一個線程進入臨界區域, 一旦一個線程封鎖了鎖對象,其他任何線程都無法通過lock語句。 當其他線程調用 lock 時, 它們會被阻塞,直到第一個線程釋放鎖對象;

Warning)把解鎖操作包括在了 finally 子句中是至關重要的。 如果在臨界區的代碼拋出異常, 鎖必須被釋放, 否則, 其他線程將永遠阻塞下去;

Attention)

  • A1)鎖是可重入的, 因為線程可以重復地獲得已持有的鎖;
  • A2)鎖保持一個持有計數來跟蹤對 lock 方法的嵌套調用, 線程在每一次調用lock 都要調用 unlock 來釋放鎖;
  • A3)由于這一特性, 被一個鎖保護起來的代碼可以調用另一個使用相同的鎖的方法;

總結

以上是生活随笔為你收集整理的java线程同步——竞争条件的荔枝+锁对象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。