疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

使用Java的Callable接口运行线程


 

        Runnable和Callable的区别:

  (1)Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的

  (2)Callable规定的方法是call(),Runnable规定的方法是run()

  (3)Callable的任务执行后可返回值,而Runnable的任务是不能返回值(是void)

  (4)call方法可以抛出异常,run方法不可以

  (5)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

  (6)加入线程池运行,Runnable使用ExecutorService的execute方法,Callable使用submit方法。

  Callable接口也是位于java.util.concurrent包中。Callable接口的定义为:

  Java代码

  public interface Callable

  {

  V call() throws Exception;

  }

  测试使用代码,定义一个实现Callable接口的类OneTask:

  Java代码

  import java.util.concurrent.Callable;

  public class OneTask implements Callable {//callable有个,这个V就是call函数的返回值类型

  private int id;

  public OneTask(int id){

  this.id = id;

  }

  @Override

  public String call() throws Exception {//这儿可以抛出异常,而Runnable接口的run函数不可以

  int i=5;

  while (i>=0) {

  System.out.println("Thread "+ id +" is working");

  Thread.sleep(1000);

  i--;

  }

  return "result of Test2 " + id; //Runnable接口的run函数是没有返回值的

  }

  }

  执行Callable的线程的方法可以借助FutureTask或者加入到线程池中。首先看怎么用FutureTash执行,代码如下:

  Java代码

  import java.util.concurrent.Callable;

  import java.util.concurrent.FutureTask;

  public class Test1 {

  public static void main(String[] args) {

  Callable oneCallable = new OneTask(1);

  FutureTask ft= new FutureTask(oneCallable);

  //FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了Future和Runnable接口

  new Thread(ft).start();

  while(!ft.isDone()){

  try {

  System.out.println("检查线程执行完了吗...");

  Thread.sleep(1000);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  }

  String result = "";

  try {

  result = ft.get();

  } catch (Exception e) {

  e.printStackTrace();

  }

  System.out.println(result);

  }

  }

  FutureTash扮演监督的角色,主线程通过不断询问实现Callable的类对应的线程是否执行完毕,最后可以得到返回的结果。通过线程池的方式如下:

  Java代码

  import java.util.ArrayList;

  import java.util.concurrent.ExecutorService;

  import java.util.concurrent.Executors;

  import java.util.concurrent.Future;

  public class Test3 {

  public static void main(String[] args){

  // TODO Auto-generated method stub

  ExecutorService exec = Executors.newCachedThreadPool();

  ArrayList> results = new ArrayList>();

  //Future 相当于是用来存放Executor执行的结果的一种容器

  for (int i = 0; i < 10; i++) {

  results.add(exec.submit(new OneTask(i)));

  }

  for (Future fs : results) {

  if (fs.isDone()) {

  try {

  System.out.println(fs.get());

  } catch (Exception e) {

  e.printStackTrace();

  }

  } else {

  System.out.println("Future result is not yet complete");

  }

  }

  exec.shutdown();

  }

  } 

  想要高薪入职名企,最好的方法就是参加疯狂软件学院的Java培训(疯狂软件学院http://www.fkjava.org/抢座热线:020-28309358,020-28309378咨询QQ:707552864,544627560 )。强大的教师队伍倾情授课,带领学生走近编程,感受编程,热爱编程。疯狂软件学院打造名企技术经理,成为中国软件产业的中流砥柱:全真企业需求,项目小组管理,大量实操项目的训练,企业全真案例教学,四个半月掌握近8~10万代码量,达到技术经理的代码掌握量。学成至少相当于两年工作经验。