Java中的不安全集合類(一)

常用的線程不安全集合:
ArrayList
LinkedList
ArraySet
HashMap

線程不安全:

比如當A線程在操作數據時,B線程突然進來,A線程要添加的位置佔用,後續A線程將此數據(B線程的數據)修改爲自己的數據這時就會空值(java.lang.NullPointerException) 或者是拋出異常(java.util.ConcurrentModificationException)
JAVA版本:1.8

ArrayList 示例:

我們使用 15 個線程同時向 List 接口下 ArrayList 集合 中添加數據:

    public static void main(String[] args) {
        //新建一個ArrayList集合 strings
        List<String> strings = new ArrayList<>();
        //循環創建線程 向strings中添加數據
        for (int i = 1; i <= 15; i++) {
            new Thread(() -> {
                strings.add(UUID.randomUUID().toString().substring(0, 5));
                System.out.println(Thread.currentThread().getName()+":"+strings);
            },String.valueOf(i)).start();
        }
    }

執行後我們看到:

Exception in thread "2" Exception in thread "5" java.util.ConcurrentModificationException

線程"2" 與 線程 “5” 拋出異常:
java.util.ConcurrentModificationException (併發修改異常)

我們來看 ArrayList 的add() 方法源碼一步步解析

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

ArrayLisrt 底層 爲一個數組
首先更新了 數組的長度,然後將我們的屬性賦給指定的數組下標
故:ArrayList 爲線程不安全集合


LinkedList 示例:

我們使用 15 個線程同時向 List 接口下 LinkedList 集合 中添加數據:

List<String> strings = new LinkedList<>();

執行後我們看到:

Exception in thread "12" Exception in thread "4" java.lang.NullPointerException

超過一半的線程拋出:
java.lang.NullPointerException (空指針異常)

我們來看 LinkedList 的add() 方法源碼一步步解析

public boolean add(E e) {
        linkLast(e);
        return true;
    }
     /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

LinkedList 底層是基於雙向鏈表實現的,也是實現了 List 接口,所以也擁有 List 的一些特點
可見每次插入都是移動指針
故:LinkedList 爲線程不安全集合

如何解決線程不安全問題請查看

Java中的不安全集合類(二)
本人小白,如有編寫不合理的地方請大神指點,輕噴

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章