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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

这8种保证线程安全的技术你都知道吗?

發布時間:2025/3/16 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 这8种保证线程安全的技术你都知道吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

并發情況下如何保證數據安全,一直都是開發人員每天都要面對的問題,稍不注意就會出現數據異常,造成不可挽回的結果。筆者根據自己的實際開發經驗,總結了下面幾種保證數據安全的技術手段:

  • 無狀態

  • 不可變

  • 安全的發布

  • volatile

  • synchronized

  • lock

  • cas

  • threadlocal

  • 一.無狀態

    我們都知道只有多個線程訪問公共資源的時候,才可能出現數據安全問題,那么如果我們沒有公共資源,是不是就沒有這個問題呢?

    public class NoStatusService {public void add(String status) {System.out.println("add status:" + status);}public void update(String status) {System.out.println("update status:" + status);} }

    二.不可變

    如果多個線程訪問公共資源是不可變的,也不會出現數據的安全性問題。

    public class NoChangeService { public static final String DEFAULT_NAME = "abc";public void add(String status) {System.out.println("add status:" + status);} }

    三.安全的發布

    如果類中有公共資源,但是沒有對外開放訪問權限,即對外安全發布,也沒有線程安全問題

    public class SafePublishService { private String name;public String getName() { return name;}public void add(String status) {System.out.println("add status:" + status);} }

    四.volatile

    如果有些公共資源只是一個開關,只要求可見性,不要求原子性,這樣可以用volidate關鍵字定義來解決問題。

    public class FlagService {public volatile boolean flag = false;public void change() { if (flag) {System.out.println("return"); return;} flag = true;System.out.println("change");} }

    五.synchronized

    使用JDK內部提供的同步機制,這也是使用比較多的手段,分為:方法同步 和 代碼塊同步,我們優先使用代碼塊同步,因為方法同步的范圍更大,更消耗性能。每個對象內部都又一把鎖,只有搶答那把鎖的線程,才能進入代碼塊里,代碼塊執行完之后,會自動釋放鎖。

    public class SyncService {private int age = 1;public synchronized void add(int i) {age = age + i; System.out.println("age:" + age);}public void update(int i) {synchronized (this) {age = age + i; System.out.println("age:" + age);} } }

    六.lock

    除了使用synchronized關鍵字實現同步功能之外,JDK還提供了lock顯示鎖的方式。它包含:可重入鎖、讀寫鎖 等更多更強大的功能,有個小問題就是需要手動釋放鎖,不過在編碼時提供了更多的靈活性。

    public class LockService { private ReentrantLock reentrantLock = new ReentrantLock(); public int age = 1;public void add(int i) { try {reentrantLock.lock();age = age + i; System.out.println("age:" + age);} finally {reentrantLock.unlock(); } } }

    七.cas

    JDK除了使用鎖的機制解決多線程情況下數據安全問題之外,還提供了cas機制。這種機制是使用CPU中比較和交換指令的原子性,JDK里面是通過Unsafe類實現的。cas需要四個值:舊數據、期望數據、新數據 和 地址,比較舊數據 和 期望的數據如果一樣的話,就把舊數據改成新數據,當前線程不斷自旋,一直到成功為止。不過可能會出現aba問題,需要使用AtomicStampedReference增加版本號解決。其實,實際工作中很少直接使用Unsafe類的,一般用atomic包下面的類即可。

    public class AtomicService { private AtomicInteger atomicInteger = new AtomicInteger();public int add(int i) { return atomicInteger.getAndAdd(i);} }

    八.threadlocal

    除了上面幾種解決思路之外,JDK還提供了另外一種用空間換時間的新思路:threadlocal。它的核心思想是:共享變量在每個線程都有一個副本,每個線程操作的都是自己的副本,對另外的線程沒有影響。特別注意,使用threadlocal時,使用完之后,要記得調用remove方法,不然可能會出現內存泄露問題。

    public class ThreadLocalService { private ThreadLocal<Integer> threadLocal = new ThreadLocal<>();public void add(int i) {Integer integer = threadLocal.get();threadLocal.set(integer == null ? 0 : integer + i);}}

    總結

    本文介紹了8種多線程情況下保證數據安全的技術手段,當然實際工作中可能會有其他。技術沒有好壞之分,主要是看使用的場景,需要在不同的場景下使用不同的技術。

    有道無術,術可成;有術無道,止于術

    歡迎大家關注Java之道公眾號

    好文章,我在看??

    總結

    以上是生活随笔為你收集整理的这8种保证线程安全的技术你都知道吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

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