Callable,Runnable比较及用法

来源:互联网 发布:汽车销售网站源码 编辑:程序博客网 时间:2024/05/16 04:04
编写多线程程序一般有三种方法,Thread,Runnable,Callable.

Runnable和Callable的区别是,
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以

(4)运行Callable任务可以拿到一个Future对象,Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如果线程没有执行完,Future.get()方法可能会阻塞当前线程的执行;如果线程出现异常,Future.get()会throws InterruptedException或者ExecutionException;如果线程已经取消,会跑出CancellationException。取消由cancel 方法来执行。isDone确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明Future<?> 形式类型、并返回 null 作为底层任务的结果。Future接口的定义如下:


Future模式
Future模式在请求发生时,会先产生一个Future凭证给发出请求的客户,它的作用就像是Proxy物件,同时,由一个新的执行线程持续进行目标物件的生成(Thread-Per-Message),真正的目标物件生成之后,将之设定至Future之中,而当客户端真正需要目标物件时,目标物件也已经准备好,可以让客户提取使用。
结合JDK的Future来看,就是你run线程后,你可以把线程的返回值赋给Future并返回一个Future对象。这时你可以立即拿到这个对象,然后进行下面的逻辑。但是如果你要get这个Future中的线程结果,就会被阻塞直到线程结束。
就相当于现在的期房,你把手续和钱都交上去了,就可以马上拿到合同,但只有合同没有房子。这个时候你已经是有房一族了,你可以先去买家电买装修(走下面的其他逻辑)。但是你要把家电和装修放进去,就必须等到房子完工(阻塞)。


               
public interface Future<T>
{
    V get() throws ...;
    V get(long timeout, TimeUnit unit) throws ...;
    void cancle(boolean mayInterrupt);
    boolean isCancelled();
    boolean isDone();
}
具体的实现类为java.util.concurrent.FutureTask<V>。


1、通过实现Callable接口来创建Thread线程:


其中,Callable接口(也只有一个方法)定义如下:


public interface Callable<V>   
{   
    V call() throws Exception;   

步骤1:创建实现Callable接口的类SomeCallable<Integer>;


步骤2:创建一个类对象:


      Callable<Integer> oneCallable = new SomeCallable<Integer>();
 
步骤3:由Callable<Integer>创建一个FutureTask<Integer>对象:


      FutureTask<Integer> oneTask = new FutureTask<Integer>(oneCallable);
FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口,他的run方法中实际上会调用oneCallable.call()。


步骤4:由FutureTask<Integer>创建一个Thread对象:


       Thread oneThread = new Thread(oneTask);
  
步骤5:启动线程:


       oneThread.start();
  
  
  
2、通过线程池来创建线程:


步骤1:创建线程池:


      ExecutorService pool = Executors.newCachedThreadPool();


步骤2:通过Runnable对象或Callable对象将任务提交给ExecutorService对象:


      Future<Integer> submit(Callable<Integer> task);



网上的例子

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. import java.util.concurrent.*;  
  2.   
  3. public class Test {  
  4.   
  5.       
  6.     public static void main(String[] args) throws InterruptedException,  
  7.             ExecutionException {  
  8.         final ExecutorService exec = Executors.newFixedThreadPool(5);  
  9.         Callable<String> call = new Callable<String>() {  
  10.             public String call() throws Exception {  
  11.                 Thread.sleep(1000 * 10);//休眠指定的时间,此处表示该操作比较耗时  
  12.                 return "Other less important but longtime things.";  
  13.             }  
  14.         };  
  15.         Future<String> task = exec.submit(call);  
  16.         //重要的事情  
  17.         System.out.println("Let's do important things. start");  
  18.         Thread.sleep(1000 * 3);  
  19.         System.out.println("Let's do important things. end");  
  20.   
  21.         //不重要的事情  
  22.         while(! task.isDone()){  
  23.             System.out.println("still waiting....");  
  24.             Thread.sleep(1000 * 1);  
  25.         }  
  26.         System.out.println("get sth....");  
  27.         String obj = task.get();  
  28.         System.out.println(obj);  
  29.         //关闭线程池  
  30.         exec.shutdown();  
  31.     }  
  32. }  

输出结果:Let's do important things. start
Let's do important things. end
still waiting....
still waiting....
still waiting....
still waiting....
still waiting....
still waiting....
still waiting....
get sth....
Other less important but longtime things.
0 0
原创粉丝点击