集合線程安全問題:第一章:集合類不安全之并發(fā)修改異常

直接上ArrayList線程不安全代碼:

    package com.javaliao.backstage;
     
    import java.util.ArrayList;
    import java.util.UUID;
     
    public class Demo {
        public static void main(String[] args) {
            List arrayList = new ArrayList<String>();
            for (int i = 0; i < 30; i++) {
                new Thread(()->{
                    arrayList.add(UUID.randomUUID().toString().substring(0,8));
                    System.out.println(arrayList);
                },String.valueOf(i)).start();
            }
        }
    }

控制臺(tái)直接報(bào)錯(cuò):

只要你干過電商項(xiàng)目的基本上都見過,java.util.ConcurrentModificationException并發(fā)修改異常

錯(cuò)誤分析:

    故障現(xiàn)象:java.util.ConcurrentModificationException并發(fā)修改異常
    導(dǎo)致原因:并發(fā)爭(zhēng)取修改導(dǎo)致,一個(gè)線程正在寫,一個(gè)線程過來爭(zhēng)搶,導(dǎo)致線程寫的過程被其他線程打斷,導(dǎo)致數(shù)據(jù)不一致。
    解決方案

          第一種:使用List arrayList = new Vector<>();它的底層使用了synchronized加鎖,但是并發(fā)下降

          第二種:使用List arrayList = Collections.synchronizedList(new ArrayList<String>());使用工具類,線程同步

          第三種:使用List arrayList = new CopyOnWriteArrayList<>();寫時(shí)復(fù)制

    優(yōu)化建議

使用第三種解決方案較好
直接上HashSet線程不安全代碼:

    package com.javaliao.backstage;
     
    import java.util.*;
     
    public class Demo {
        public static void main(String[] args) {
            Set hashSet = new HashSet<String>();
            for (int i = 0; i < 30; i++) {
                new Thread(()->{
                    hashSet.add(UUID.randomUUID().toString().substring(0,8));
                    System.out.println(hashSet);
                },String.valueOf(i)).start();
            }
        }
    }

控制臺(tái):

錯(cuò)誤分析:

    故障現(xiàn)象:java.util.ConcurrentModificationException并發(fā)修改異常
    導(dǎo)致原因:并發(fā)爭(zhēng)取修改導(dǎo)致,一個(gè)線程正在寫,一個(gè)線程過來爭(zhēng)搶,導(dǎo)致線程寫的過程被其他線程打斷,導(dǎo)致數(shù)據(jù)不一致。
    解決方案

        第一種:Set<String> hashSet = Collections.synchronizedSet(new HashSet<>());

        第二種:Set<String> hashSet = new CopyOnWriteArraySet();(它的底層還是 new CopyOnWriteArrayList<>();)
直接上HashMap線程不安全代碼:

    package com.javaliao.backstage;
     
    import java.util.*;
     
    public class Demo {
        public static void main(String[] args) {
            Map<String,String> hashMap = new HashMap<>();
            for (int i = 0; i < 30; i++) {
                new Thread(()->{
                    hashMap.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
                    System.out.println(hashMap);
                },String.valueOf(i)).start();
            }
        }
    }

控制臺(tái):

錯(cuò)誤分析:

    故障現(xiàn)象:java.util.ConcurrentModificationException并發(fā)修改異常
    導(dǎo)致原因:并發(fā)爭(zhēng)取修改導(dǎo)致,一個(gè)線程正在寫,一個(gè)線程過來爭(zhēng)搶,導(dǎo)致線程寫的過程被其他線程打斷,導(dǎo)致數(shù)據(jù)不一致。
    解決方案:

             第一種:Map<String,String> hashMap = new ConcurrentHashMap<>();

             第二種:Map<String,String> hashMap = Collections.synchronizedMap(new HashMap<>());