CompletionService 实现 Dubbo 中的 Forking Cluster
并行的查询三个业务数量接口,拿到最先返回的数据,并取消剩下的任务
public class CompletionServiceDemo {
public static void main(String[] args) {
Integer num = getNum();
System.out.println("最终的数据量:" + num);
}
private static Integer getNum(){
ExecutorService executorService = new ThreadPoolExecutor(
3,
10,
0L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(5),
new ReNameThreadFactory("queryNum"));
CompletionService<Integer> cs = new ExecutorCompletionService<>(executorService);
List<Future<Integer>> list = new ArrayList<>(3);
list.add(cs.submit(() -> getNum1()));
list.add(cs.submit(() -> getNum2()));
list.add(cs.submit(() -> getNum3()));
Integer result = 0;
try {
for (int i = 0;i < 3;i++){
result = cs.take().get();
System.out.println("最先得到的数据:" + result);
if (result != null){
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
for (Future future : list){
future.cancel(true);
}
}
return result;
}
private static Integer getNum1(){
try {
System.out.println("查询手机银行业务数量");
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"任务被取消");
}
System.out.println("得到手机银行业务数量100");
return 100;
}
private static Integer getNum2(){
try {
System.out.println("查询网银业务数量");
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"任务被取消");
}
System.out.println("得到网银业务数量200");
return 200;
}
private static Integer getNum3(){
try {
System.out.println("查询云管家业务数量");
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"任务被取消");
}
System.out.println("得到云管家业务数量300");
return 300;
}
//设置业务线程名称
static class ReNameThreadFactory implements ThreadFactory {
private static final AtomicInteger POOLNUMBER = new AtomicInteger(1);
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final String namePrefix;
public ReNameThreadFactory(@NonNull String prefix) {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
//组装线程前缀
namePrefix = prefix + "-poolNumber:" + POOLNUMBER.getAndIncrement() + "-threadNumber:";
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
}
}