有返回值的线程定义需继承Callable接口,然后将线程交给执行器,提交线程需要使用submit()方法。
demo 示例:
使用线程执行器处理有返回值的线程
某驾校有4辆考试车,有8个学生要进行考试,要求分别获取学生考试的时间。
//学生考试线程类
public class Student implements Callable<Long>{
String name;
Student(String name){
this.name = name;
}
public Long call(){
System.out.println(name+"开始考试了");
long start = System.nanoTime();
int num = (int)(Math.random()*Integer.MAX_VALUE);
for(int i=0;i<num;i++);
long end = System.nanoTime();
System.out.println(name + "考试完毕");
Long time = end-start;
return time;
}
public String getName(){
return name;
}
}
//线程池执行器类
public class TestRoom{
ExecutorService testPool;
Map<Student,Future<Long>>stuToTimeMap;
TestRoom(){
//获取固定数量线程池
testPool = Executors.newFixedThreadPool(4);
stuToTimeMap = new HashMap<Student,Future<Long>>();
}
public void test(Student student){
//有返回值的线程提交实现了Callable接口的对象使用submit()方法。
Future<Long> result = testPool.submit(student);
stuToTimeMap.put(student,result);
}
public Long getTime(Student student){
Future<Long> result = stuToTimeMap.get(student);
try{
return result.get();
}catch(InterruptedException| ExecutionException e){
e.printStackTrace();
return null;
}
}
public void endTest(){
if(!testPool.isShutdown()){
testPool.shutdown();
}
}
}
//启动测试类
public class Index{
public static void main(String [] args ){
int studentNum = 8;
List<Student> stuList = new ArrayList<Student>();
TestRoom testRoom = new TestRoom();
for(int i =0;i<studentNum;i++){
Student student = new Student("学生"+ i);
testRoom.test(student);
stuList.add(student);
}
for(Student student : stuList){
System.out.println(student.getName() + "考试时间为:" +testRoom.getTime(student)+"纳秒" );
}
testRoom.endTest();
}
}
运行结果:
学生0开始考试了
学生3开始考试了
学生2开始考试了
学生1开始考试了
学生2考试完毕
学生4开始考试了
学生0考试完毕
学生1考试完毕
学生4考试完毕
学生3考试完毕
学生0考试时间为:12610000纳秒
学生7开始考试了
学生6开始考试了
学生5开始考试了
学生7考试完毕
学生1考试时间为:12478800纳秒
学生5考试完毕
学生6考试完毕
学生2考试时间为:5363000纳秒
学生3考试时间为:12573900纳秒
学生4考试时间为:6957100纳秒
学生5考试时间为:95400纳秒
学生6考试时间为:74100纳秒
学生7考试时间为:190200纳秒