import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class CallableDeml implements Callable<List<String>> {
private int taskNum;

public CallableDeml(int taskNum){
this.taskNum=taskNum;
}
public List<String> call() throws Exception {
Date dateImpl = new Date();
List<String> list = new ArrayList<String>();
for(int i=0;i<100;i++){
String num=String.valueOf(taskNum*100+i);
list.add(num);
}
Date dateImp2 = new Date();
long time = dateImp2.getTime()-dateImpl.getTime();
System.out.println("线程"+taskNum+"任务时间【"+time+"毫秒】");
return list;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
System.out.println("-------程序开始运行--------");
Date date1 =new Date();
int taskSize=5;
//创建一个线程池
ExecutorService pool=Executors.newFixedThreadPool(taskSize);
//创建多个有返回值的任务
List<Future<List<String>>> list= new ArrayList<Future<List<String>>>();
for(int i=0;i<taskSize;i++){
Callable<List<String>> c=new CallableDeml(i);
Future<List<String>> f=pool.submit(c);//提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
list.add(f);

}
//关闭线程池
pool.shutdown();
Date date2= new Date();
System.out.println("--------程序结束---------,程序运行时间【"+(date2.getTime()-date1.getTime())+"毫秒】");
//获取所有并发任务的运行结果
for(Future<List<String>> f:list){
//从Future对象上获取任务的返回值,并输出到控制台
List<String> subList =f.get();
for(String s:subList){
System.out.println(s);
}
}



}
     
}public List<String> call() throws Exception请问这个覆写的call()方法是何时被调用的?
看了半天没看出来  本人刚学java  求大师指点一下

解决方案 »

  1.   

    CallableDeml其实用到的是command设计模式,也就是把call这个方法封装成类,然后扔给ExecutorService中的线程处理。ExecutorService的处理方式属于多线程设计模式中的 “Future模式”(可以参考《Java多线程设计模式详解》第九章)。submit方法立即返回一个CallableDeml的代理,也就是Future对象(之后可以通过它取得call的计算结果)。待线程执行完call方法时,就可以通过Future获取到call的返回值(如果在线程执行完call之前通过Future获取返回值,将会被阻塞)。
    所以call方法是在ExecutorService创建的线程中被调用。submit方法只是将CallableDeml对象给线程处理的动作而已(当然提交完了,线程池将被通知开工!)。