0
点赞
收藏
分享

微信扫一扫

Java中ExecutorService线程的Callable的future.get()方法堵塞当前线程解决方法


 场景

Java中ExecutorService线程池的使用(Runnable和Callable多线程实现):

在上面学习线程池ExecutorService的使用,实现Callable接口,并获取返回结果时

需要注意future的get()方法会堵塞当前线程的执行。

即当前线程执行结束并获取到结果之后才会继续执行下个线程。

这样就无法实现多线程的效果。

比如:

//        ArrayList<String> resultList = new ArrayList<>();
// for (int i = 0; i < 5; i++) {
// Future<String> submit = executorService.submit(new CustomTask());
// String result = null;
// try {
// result = submit.get();//get方法能获取到当前线程的执行结果,但是会堵塞当前线程
// resultList.add(result);
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
// }

执行效果为 

Java中ExecutorService线程的Callable的future.get()方法堵塞当前线程解决方法_java

注:

实现

1、解决方式为创建一个数组存储所有的future,在所有线程循环结束以后再遍历list获取结果。

ArrayList<Future<String>> resultList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Future<String> submit = executorService.submit(new CustomTask());
resultList.add(submit);
}
resultList.forEach(result -> {
try {
System.out.println(result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});

上面这种执行效果

 

Java中ExecutorService线程的Callable的future.get()方法堵塞当前线程解决方法_i++_02

2、完整示例代码

package com.ruoyi.demo.Executor;

import com.ruoyi.common.utils.DateUtils;

import java.util.ArrayList;
import java.util.concurrent.*;

public class CallableDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
ArrayList<Future<String>> resultList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Future<String> submit = executorService.submit(new CustomTask());
resultList.add(submit);
}
resultList.forEach(result -> {
try {
System.out.println(result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
}

class CustomTask implements Callable<String> {

@Override
public String call() throws Exception {
String threadName = Thread.currentThread().getName();
System.out.println("线程名:" + threadName + " 开始时间:" + DateUtils.getTime());
System.out.println("系统需要业务操作1秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "threadName = "+threadName +" 结束时间:"+DateUtils.getTime();
}
}

举报

相关推荐

0 条评论