List集合:

package com.unsafe;

import java.util.ArrayList;
import java.util.UUID;

public class ListTest {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i <20 ; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

在这样并发的情况下,ArrayList是不安全的,系统会报ConcurrentModificationException(并发修改异常),解决方案:

package com.unsafe;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

public class ListTest {
    public static void main(String[] args) {
        /*并发情况下ArrayList是不安全的,解决方案
        1.List<String> list = Collections.synchronizedList(new ArrayList<>());
        2.List<String> list = new CopyOnWriteArrayList<>();
        * */
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i <20 ; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

set集合不安全解决方法与以上类似

 

HashMap不安全

package com.unsafe;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class MapTest {
    public static void main(String[] args) {
        //HashMap默认有初始化容量和负载因子,初始化容量为16,负载因子0.75,当数据达到总容量*负载因子时就要进行扩容
        Map<String,String> map = new HashMap<>();

        for (int i = 0; i <30 ; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,3));
                System.out.println(map);
            }).start();
        }
    }

}

多线程的情况下使用HashMap同样会报错ConcurrentModificationException(并发修改异常),所以并发情况下用ConcurrentHashMap。

并发下的HashMap,HashMap是线程不安全的,虽然HashTable可以代替HashMap,达到线程安全的目的,但是HashTable是用一个全局锁来同步不同的线程,这样性能就大大降低了,而ConcurrentHashMap用volatile修饰变量保证了安全高效的读操作,而利用锁分段技术保证了高并发情况下的写操作。

package com.unsafe;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class MapTest {
    public static void main(String[] args) {
        //HashMap默认有初始化容量和负载因子,初始化容量为16,负载因子0.75,当数据达到总容量*负载因子时就要进行扩容
        Map<String,String> map = new ConcurrentHashMap<>();

        for (int i = 0; i <30 ; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,3));
                System.out.println(map);
            }).start();
        }
    }

}

 

posted on 2021-06-23 16:38  Bjtino  阅读(43)  评论(0)    收藏  举报