JUC练习5——解决List,Set,Map多线程下的同步安全问题
1,对List进行优化
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class JucTest3
{
public static void main(String[] args) {
/**
* 在多线程下ArrayList不安全会发生同步修改异常ConcurrentModificationException
* 原因:
* 解决方式:
* 1,使用Vector代替ArrayList,底层是使用synchronized来实现同步的,效率比较低
* 2,使用工具类将其转成安全的:List list = Collections.synchronizedList(new ArrayList<>());
* 3,使用JUC下的CopyOnWriteArrayList:List list = new CopyOnWriteArrayList<>();,使用lock实现同步,效率高
* 它会在写入的时候,避免多线程下同时写入,将其它线程写入的数据覆盖,所以如果该线程想要写入数据时,它只能将数据复制一份出来
* 在复制的数据上面做出修改后,再同步会原来的数据中
*/
List 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();
}
}
}
2,对Set进行优化
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
public class JucTest5
{
public static void main(String[] args) {
/**
* hashSet本质上是hashMap,他利用了hashMap中key的不唯一性来实现数据的不重复
* 多线程下hashSet是不安全的,会出现ConcurrentModificationException
* 解决方案
* 1,Set set = Collections.synchronizedSet(new HashSet());
* 2,Set set =new CopyOnWriteArraySet<>();
*/
//Set set = new HashSet();
//Set set = Collections.synchronizedSet(new HashSet());
Set set =new CopyOnWriteArraySet<>();
for (int i=0;i<60;i++)
{
new Thread(()->
{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set.toString());
},String.valueOf(i)).start();
}
}
}
3,对Map进行优化
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
public class JucTest6
{
public static void main(String[] args) {
/**
* HashMap初始容量为16,扩展因子为0,75
* 多线程下hashMap是不安全的,会出现ConcurrentModificationException
* 解决方案
* 1,Map map = Collections.synchronizedMap(new HashMap<>());
* 2,Map map = new ConcurrentHashMap<>();
*/
//Map map = new HashMap<>();
//Map map = Collections.synchronizedMap(new HashMap<>());
Map map = new ConcurrentHashMap<>();
for (int i=0;i<60;i++)
{
final int temp = i;//为了线程内可以读取到变量
new Thread(()->
{
map.put(UUID.randomUUID().toString().substring(0,5),String.valueOf(temp));
System.out.println(map);
},String.valueOf(i)).start();
}
}
}