併發編程

atomicReference類型提供了較爲奇葩的一些方法,如下圖
在這裏插入圖片描述

  1. int addAndGet(int delta):以原子方式將給定值與當前值相加。 實際上就是等於線程安全版本的i =i+delta操作。
  2. boolean compareAndSet(int expect, int update):如果當前值 == 預期值,則以原子方式將該值設置爲給定的更新值。 如果成功就返回true,否則返回false,並且不修改原值。
  3. int decrementAndGet():以原子方式將當前值減 1。 相當於線程安全版本的–i操作。
  4. int get():獲取當前值。
  5. int getAndAdd(int delta):以原子方式將給定值與當前值相加。 相當於線程安全版本的t=i;i+=delta;return t;操作。
  6. int getAndDecrement():以原子方式將當前值減 1。 相當於線程安全版本的i–操作。
  7. int getAndIncrement():以原子方式將當前值加 1。 相當於線程安全版本的i++操作。
  8. int getAndSet(int newValue): 以原子方式設置爲給定值,並返回舊值。 相當於線程安全版本的t=i;i=newValue;return t;操作。
  9. int incrementAndGet():以原子方式將當前值加 1。 相當於線程安全版本的++操作 在這裏插入圖片描述
    synchronized:互斥鎖,內置鎖,只有一個線程能用來鎖住了service方法,所以synchronizedFactorizer這個是線程安全的,但是有個性能的問題啊
    在這裏插入圖片描述
    重入鎖:線程獲得鎖count+1,線程退出count-1,count==0時候鎖釋放 下圖代碼調用了LoggingWidget的doSomething的時候會上鎖,然後調用super.doSomething已經沒鎖了,如果沒有可重入鎖,調用此方法永遠無法活得鎖。
    在這裏插入圖片描述
    值得留意的是,並不是加了synchronized一定能保持原子性,A線程執行contains後,準備執行add前,B線程又執行一次contains,保持不了符合操作原子性
    在這裏插入圖片描述

解決辦法如下 設置了兩個變量 hits 和cacheHists,同步代碼塊引用這兩個變量都要加入同步,同步代碼塊之外的代碼就不用,因爲以獨佔方式訪問變量
在這裏插入圖片描述