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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java并发排它锁_Java并发编程进阶——锁(解析)

發布時間:2023/12/15 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java并发排它锁_Java并发编程进阶——锁(解析) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、鎖是什么

java開發中進行并發編程時針對操作同一塊區域時,如果不加鎖會出現并發問題,數據不是自己預計得到的值。我覺得有點像mysql事務中臟讀、不可重復讀、幻讀的問題。加鎖的目的是為了保證同一時間只有我一個人操作同一個資源。

二、如何在代碼里面加鎖

jdk提供給了我們很多鎖的實現方式,用于各種情況鎖的使用:

  • 使用synchronized修飾方法、修飾代碼塊等;
  • 使用ReentrantLock來獲取鎖;
  • ReadWriteLock讀寫分開的讀寫鎖;
  • ReentrantReadWriteLock;
  • 三、這些鎖有什么區別

    Ⅰ、實現原理不同

    synchronized是鎖實現原理是jdk實現的:

    public class SynchronizedDemo {public static void main(String[] args) {Object o = new Object();synchronized (o){System.out.println("ReentrantLockDemo");}} }

    使用synchronized修飾的代碼會在編譯時加上monitorenter、monitorexit進行修飾,那么問題來了,為什么用這個修飾后就能夠保證線程執行過程中的安全呢?
    因為jdk在執行monitorenter、monitorexit區塊的時候是保證原子性的,要么執行完成要么執行不完成。synchronized修飾的代碼塊有可視性、原子性、順序性(防止重排序)。

    ReentrantLock是怎么實現鎖的機制呢?

    通過繼承AbstractQueuedLongSynchronizer(AQS)來進行鎖的,實現原理是AQS中有一個變量來控制是否獲取到了鎖,通過Unsafe的CAS操作來獲取鎖,從而保證線程安全。

    那么問題來了?CAS操作的ABA問題如何解決?

    concurrent包中有提供AtomicStampedReference來解決ABA問題,也就是在CAS操作的同時需要再增加版本的判斷,從而保證不出現ABA的問題。

    public class SolveCAS {// 主內存共享變量,初始值為1,版本號為1private static AtomicStampedReference<Integer> atomicStampedReference = newAtomicStampedReference<>(1, 1);public static void main(String[] args) {// t1,期望將1改為10new Thread(() -> {// 第一次拿到的時間戳int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName()+" 第1次時間戳:"+stamp+" 值為:"+atomicStampedReference.getReference());// 休眠5s,確保t2執行完ABA操作try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }// t2將時間戳改為了3,cas失敗boolean b = atomicStampedReference.compareAndSet(1, 10, stamp, stamp + 1);System.out.println(Thread.currentThread().getName()+" CAS是否成功:"+b);System.out.println(Thread.currentThread().getName()+" 當前最新時間戳:"+atomicStampedReference.getStamp()+" 最新值為:"+atomicStampedReference.getReference());},"t1").start();// t2進行ABA操作new Thread(() -> {// 第一次拿到的時間戳int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName()+" 第1次時間戳:"+stamp+" 值為:"+atomicStampedReference.getReference());// 休眠,修改前確保t1也拿到同樣的副本,初始值為1try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }// 將副本改為20,再寫入,緊接著又改為1,寫入,每次提升一個時間戳,中間t1沒介入atomicStampedReference.compareAndSet(1, 20, stamp, stamp + 1);System.out.println(Thread.currentThread().getName()+" 第2次時間戳:"+atomicStampedReference.getStamp()+" 值為:"+atomicStampedReference.getReference());atomicStampedReference.compareAndSet(20, 1, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);System.out.println(Thread.currentThread().getName()+" 第3次時間戳:"+atomicStampedReference.getStamp()+" 值為:"+atomicStampedReference.getReference());},"t2").start();} }

    Ⅱ、使用場景不同

    ReadWriteLock可以使用在讀多寫少的情況,盡量提升并發的能力 ReadWriteLock、synchronized使用的是獨占鎖,但是jdk對synchronized在編譯時會有優化。

    更多關于Java的技術和資訊可以關注我的專欄:

    Java架構筑基?zhuanlan.zhihu.com

    專欄免費給大家分享Java架構的學習資料和視頻

    總結

    以上是生活随笔為你收集整理的java并发排它锁_Java并发编程进阶——锁(解析)的全部內容,希望文章能夠幫你解決所遇到的問題。

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