集合線程安全問題:第一章:集合類不安全之并發(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<>());