不安全的集合類
阿新 • • 發佈:2022-04-18
List不安全
// java.util.ConcurrentModificationException 併發修改異常! public class ListTest { public static void main(String[] args) { // 併發下ArrayList是不安全的 /** * 解決方案 * 1.List<String> list = new Vector<>(); * 2.List<String> list = Collections.synchronizedList(new ArrayList<>()); * 3.List<String> list = new CopyOnWriteArrayList<>(); */ // List<String> list = new Vector<>(); // List<String> list = Collections.synchronizedList(new ArrayList<>()); // CopyOnWrite寫入時複製 COW 計算機程式設計領域的一種優化策略 // 多個執行緒呼叫的時候,list,讀取的時候,固定的,寫入(覆蓋) // 在寫入的時候避免覆蓋,造成資料問題! // 獨寫分離 // CopyOnWriteArrayList比Vector nb在哪裡? List<String> list = new CopyOnWriteArrayList<>(); for (int i = 1; i < 11; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(list); }, String.valueOf(i)).start(); } } }
Set不安全
/** * 同理可證: ConcurrentModificationException * 1.Set<String> set = Collections.synchronizedSet(new HashSet<>()); * 2.Set<String> set = new CopyOnWriteArraySet<>(); */ public class SetTest { public static void main(String[] args) { // Set<String> set = new HashSet<>(); // Set<String> set = Collections.synchronizedSet(new HashSet<>()); Set<String> set = new CopyOnWriteArraySet<>(); for (int i = 1; i < 31; i++) { new Thread(() -> { set.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(set); },String.valueOf(i)).start(); } } }
hashSet底層是什麼?
/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
/** * Adds the specified element to this set if it is not already present. * More formally, adds the specified element <tt>e</tt> to this set if * this set contains no element <tt>e2</tt> such that * <tt>(e==null ? e2==null : e.equals(e2))</tt>. * If this set already contains the element, the call leaves the set * unchanged and returns <tt>false</tt>. * * @param e element to be added to this set * @return <tt>true</tt> if this set did not already contain the specified * element */ // add set 本質就是map key是無法重複的! public boolean add(E e) { return map.put(e, PRESENT)==null; }
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
HashMap不安全
回顧Map的基本操作
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
// ConcurrentModificationException
public class MapTest {
public static void main(String[] args) {
// map是這樣用的麼? 不是,工作中不用HashMap
// 預設等價於什麼? new HashMap<>(16, 0.75f);
// Map<String, String> map = new HashMap<>();
// Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
Map<String, String> map = new ConcurrentHashMap<>();
for (int i = 1; i < 31; i++) {
new Thread(() -> {
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5));
System.out.println(map);
},String.valueOf(i)).start();
}
}
}