1、集合类不安全
11、LIst不安全
package com.zkw.JUC并发编程.unsafe;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
//java.util.ConcurrentModificationException 并发修改异常
public class ListTest {
public static void main(String[] args) {
/**
* 并发下的 ArrayList 是不安全的
* list jdk1.2出来的
* 解决方案:
*1、List<String> list = new Vector<>();jdk1.0出来的 不建议使用
*2、List<String> list = Collections.synchronizedList(new ArrayList<String>());
*3、List<String> list = new CopyOnWriteArrayList<>();
*/
/**
* CopyWrite 写入时复制 简称COW 计算机程序设计领域的一种优化策略
* 多线程调用的时候,list,读取的时候,固定的,写入(覆盖)
* 在写入的时候避免覆盖,造成数据问题
* 读写分离
* CopyOnWriteArrayList VS Vector 优势在哪里?
* CopyOnWriteArrayList用的是Lock锁,而Vector用的是synchronized锁,前者效率比后者高
* 因为synchronized修饰的是同步方法,每一个线程多要去等锁,同一时刻只有一个线程在执行
*/
List<String> list = new CopyOnWriteArrayList<>();
for (int i = 1; i <= 100; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
1.2、Set不安全
package com.zkw.JUC并发编程.unsafe;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* 同理 java.util.ConcurrentModificationException 并发修改异常
*/
public class SetTest {
public static void main(String[] args) {
//Set<String> set = new HashSet<String>();不安全
/**
* 解决方案:
* 1、借助工具类Collections 把它转为安全的
* Set<String> set = Collections.synchronizedSet(new HashSet<String>());
* 2、使用CopyWriteArraySet
* Set<String> set = new CopyOnWriteArraySet<String>();
*/
Set<String> set = new CopyOnWriteArraySet<String>();
for (int i = 1; i <= 1000; i++) {
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set);
},String.valueOf(i)).start();
}
}
}
hashSet 底层是什么?
public HashSet() {
map = new HashMap<>();
}
// add set 本质就是 map key是无法重复的
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
private static final Object PRESENT = new Object();//不变的值
1.3、Map不安全
HashMap基本的操作
package com.zkw.JUC并发编程.unsafe;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
// java.util.ConcurrentModificationException 并发修改异常
public class MapTest {
public static void main(String[] args) {
// 默认等价于什么?new HashMap<>(16,0.75);
// Map<String, String> map = new HashMap<>();
/**
* 解决方案:
* 1、Map<String, String> map = new ConcurrentHashMap<String, String>();
* 2、Map<String, String> map = Collections.synchronizedMap(new HashMap<String,String>());
*/
Map<String, String> map = new ConcurrentHashMap<String, String>();
for (int i = 1; i <= 100; i++) {
new Thread(()->{
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
System.out.println(map);
}).start();
}
}
}
7、Callable
package com.zkw.JUC并发编程.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//new Thread(new Runnable()).start();
//new Thread(new FutureTask<V>()).start();
//new Thread(new FutureTask<V>(Callable )).start();
MyThread thread = new MyThread();
FutureTask futureTask = new FutureTask(thread);// 适配类
new Thread(futureTask,"A").start();
new Thread(futureTask,"B").start();// 结果会被缓存,效率高
Integer o = (Integer)futureTask.get();//这个get 方法可能会产生阻塞!可以把它放在最后边
//或者使用异步通信来处理
System.out.println(o);
}
}
class MyThread implements Callable<Integer>{
@Override
public Integer call() {
System.out.println(Thread.currentThread().getName()+"=>Call()");
return 1024;
}
}
细节:1、会缓存;2、结果可能需要等待,会阻塞