1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        這8種保證線程安全的技術你都知道嗎?

        共 3073字,需瀏覽 7分鐘

         ·

        2020-10-18 21:51



        并發(fā)情況下如何保證數(shù)據(jù)安全,一直都是開發(fā)人員每天都要面對的問題,稍不注意就會出現(xiàn)數(shù)據(jù)異常,造成不可挽回的結果。筆者根據(jù)自己的實際開發(fā)經(jīng)驗,總結了下面幾種保證數(shù)據(jù)安全的技術手段:
        1. 無狀態(tài)
        2. 不可變
        3. 安全的發(fā)布
        4. volatile
        5. synchronized
        6. lock
        7. cas
        8. threadlocal

        一.無狀態(tài)

        我們都知道只有多個線程訪問公共資源的時候,才可能出現(xiàn)數(shù)據(jù)安全問題,那么如果我們沒有公共資源,是不是就沒有這個問題呢?
        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); }}

        二.不可變

        如果多個線程訪問公共資源是不可變的,也不會出現(xiàn)數(shù)據(jù)的安全性問題。
        public class NoChangeService {public static final String DEFAULT_NAME = "abc";
        public void add(String status) { System.out.println("add status:" + status); }}

        三.安全的發(fā)布

        如果類中有公共資源,但是沒有對外開放訪問權限,即對外安全發(fā)布,也沒有線程安全問題
        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內部提供的同步機制,這也是使用比較多的手段,分為:方法同步 和 代碼塊同步,我們優(yōu)先使用代碼塊同步,因為方法同步的范圍更大,更消耗性能。每個對象內部都又一把鎖,只有搶答那把鎖的線程,才能進入代碼塊里,代碼塊執(zhí)行完之后,會自動釋放鎖。
        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關鍵字實現(xiàn)同步功能之外,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除了使用鎖的機制解決多線程情況下數(shù)據(jù)安全問題之外,還提供了cas機制。這種機制是使用CPU中比較和交換指令的原子性,JDK里面是通過Unsafe類實現(xiàn)的。cas需要四個值:舊數(shù)據(jù)、期望數(shù)據(jù)、新數(shù)據(jù) 和 地址,比較舊數(shù)據(jù) 和 期望的數(shù)據(jù)如果一樣的話,就把舊數(shù)據(jù)改成新數(shù)據(jù),當前線程不斷自旋,一直到成功為止。不過可能會出現(xiàn)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方法,不然可能會出現(xiàn)內存泄露問題。
        public class ThreadLocalService {private ThreadLocal threadLocal = new ThreadLocal<>();
        public void add(int i) { Integer integer = threadLocal.get(); threadLocal.set(integer == null ? 0 : integer + i); }
        }

        總結

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

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

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


        好文章,我在看??

        瀏覽 118
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            精品乱码一区二区三四区视频 | 无遮挡性视频真人免费 | 九色porny蝌蚪 | 在线豆花视频 | 摸进她的内裤里疯狂揉她小说片段 | 动漫女性被强视频 | 国产91乱伦 | 特级AAAAAAAA级大毛片 | 国产一级操逼大片 | 操逼电影网 |