前言:
本文内容:CopyOnWriteArraySet、ConcurrentHashMap、走进Callable
推荐免费JUC并发编程视频:【狂神说Java】JUC并发编程最新版通俗易懂_哔哩哔哩_bilibili
CopyOnWriteArraySet
多线程下Set安全问题
并发异常:java.util.ConcurrentModificationException
解决办法:
Collections.synchronizedSet(new HashSet<>());
new CopyOnWriteArraySet<>();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.jokerdig.unsafe;
import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.concurrent.CopyOnWriteArraySet;
public class SetTest { public static void main(String[] args) {
Set<String> set = new CopyOnWriteArraySet<>(); for(int i=1;i<10;i++){ new Thread(()->{ set.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(set); },String.valueOf(i)).start(); } } }
|
HashSet的底层
1 2 3 4 5 6 7 8
| public HashSet(){ map = new HashMap<>(); }
public boolean add(E e){ return map.put(e,PRESENT)==null; } private static final Object PRESENT = new Object();
|
ConcurrentHashMap
多线程下Map安全问题
并发异常:java.util.ConcurrentModificationException
解决办法:
Collections.synchronizedMap(new HashMap<>());
new ConcurrentHashMap<>();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.jokerdig.unsafe;
import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet;
public class MapTest { public static void main(String[] args) {
Map<String,String> map = new ConcurrentHashMap<>(); for(int i=1;i<10;i++){ new Thread(()->{ map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5)); System.out.println(map); },String.valueOf(i)).start(); } }
}
|
走进Callable
概述
Callable
接口类似于Runnable
,它们都是为其实例可能由另一个线程执行的类而设计的,但是,Runnable
不能返回结果,也不能抛出被检查的异常。
Runnable
1 2 3 4 5 6 7 8
| class myThread implements Runnable{
@Override public void run() { } }
|
代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package com.jokerdig.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 { myThread myThread = new myThread(); FutureTask futureTask = new FutureTask(myThread); new Thread(futureTask,"A").start(); new Thread(futureTask,"B").start(); Integer out = (Integer) futureTask.get(); System.out.println(out); } }
class myThread implements Callable<Integer> {
@Override public Integer call() throws Exception { System.out.println("call()"); return 1024; } }
|
运行结果
1 2 3 4
| call() 1024
Process finished with exit code 0
|
注意:
- 有缓存
- 结果耗时,会发生阻塞!