ArrayList線程不安全,如何改進?CopyOnWriteArrayList

 

1、ArrayList線程不安全測試代碼

public class testArrayListUnsafe {
    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
       
        list.forEach(System.out::println);
        for (int i = 0; i <30; i++) {
            new Thread(()-> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
            //java.util.ConcurrentModificationException
            /*
            * 1、故障現象
            *
            * 2、導致原因
            *
            * 3、解決方案
            *
            * 4、優化建議(同樣的錯誤不犯第二次)
            *
            * */
        }
    }

2、報錯

Exception in thread "24" java.util.ConcurrentModificationException

3、如何解決?

public class testArrayListUnsafe {
    public static void main(String[] args) {

        List<String> list = Collections.synchronizedList(new ArrayList<>());
                //new ArrayList<>();

        list.forEach(System.out::println);
        for (int i = 0; i <30; i++) {
            new Thread(()-> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
            //java.util.ConcurrentModificationException
            /*
            * 1、故障現象
            *
            * 2、導致原因
            *
            * 3、解決方案
            *    a.new Vector<> ();
            *    b.Collections.synchronizedList(new ArrayList<>());
            * 4、優化建議(同樣的錯誤不犯第二次)
            *
            * */
        }
    }

4、如果不許用

*    a.new Vector<> ();
*    b.Collections.synchronizedList(new ArrayList<>());

怎麼辦?

public class testArrayListUnsafe {
    public static void main(String[] args) {

        List<String> list = new CopyOnWriteArrayList<>();
                // Collections.synchronizedList(new ArrayList<>());
                //new ArrayList<>();

        list.forEach(System.out::println);
        for (int i = 0; i <30; i++) {
            new Thread(()-> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
            //java.util.ConcurrentModificationException
            /*
            * 1、故障現象
            *
            * 2、導致原因
            *
            * 3、解決方案
            *    a.new Vector<> ();
            *    b.Collections.synchronizedList(new ArrayList<>());
            * 4、優化建議(同樣的錯誤不犯第二次)
            *
            * */
        }
    }

5、爲什麼用

new CopyOnWriteArrayList<>()就能保證線程安全?

CopyOnWriteArrayList的添加元素的方法的源碼:寫時複製,讀寫分離的思想。

    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }

 

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