美文网首页Android知识Java学习笔记
Android十八章:Java线程中的Runnable,Call

Android十八章:Java线程中的Runnable,Call

作者: ppjuns | 来源:发表于2017-02-15 13:38 被阅读436次

    前言,在java线程中最常见的是Thread 和Runnable,很少见到或者用到callable等类。但是,你接触过android源码就会经常看到这些类,比如AsyncTask的源码在execute方法源码可以看到了这些类。在面试时也有可能会问到两者的区别,所以现在容许鄙人来介绍一下java中这些类的用法。

    Runnable

    Runnable一个接口类,包括一个run的接口方法:通常我们会自定义一个类去实现Runnable,这时候还可以实现其他接口方法,如果类要是继承Thread就不能再继承其他类了。

    public interface Runnable{
      public abstract void run();
    }
    

    Runnable 通常配合Thread使用,在run方法里面写耗时的操作:

    new Thread(new Runnable(){
      public void run(){
      // 
     }
    }).start();
    

    Callable

    Callable是一个泛型接口,要比Runnable强些 ,因为接口方法call有返回值,并且返回值是传入的泛型类型,还能call的过程中抛出异常。

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

    示例要配合Future或者FutureTask来执行。

    Future

    Future是一个泛型接口类,是Runnable和Callable的调度容器,就是对Runnable和Callable的结果进行操作,比如:

    1. isCancelled()取消操作,call方法任务完成前取消,返回true。
    2. isDone()判断是否操作完成,是则返回true。
    3. get()获取操作结果,会导致程序阻塞,必须等到子线程结束才会得到返回值。
    4. get(long timeout TimeUnit unit)在某时间后获取操作结果,如果在规定时间内获取不到返回值将会抛出超时异常)
    public interface Future<V>{
      boolean isCancelled();
      boolean isDone();
      V get() throws InterputeredException,ExecutionExeception;
      V get(long timeout ,TimeUnit unit)throws InterputeredException,ExecutionExeception,TimeoutExeception;
      
    }
    

    比如

    ExecutorService threadPool=Executors.newSingleThreadExecutor();
    Future future=threadPool.submit(new Callable<String>(){
      public String call()throws Exception{
        return "result";
      }
      
    });
    
    Futurn.get();//返回操作结果
    

    FutureTask

    FutureTask类同时实现了Runnable和Future<V> 两个接口,具有了两个接口的属性。

    public class FutureTask<V> implements RunnableFuture<V>{
      public FutureTask(Callable<V> callable){
           this.callable=callable;
           ...
         }
      public FutureTask(Runnable runnable,V result){
        this.callable=Executors.callable(runnable,result);
        ...
      }
      boolean isCancelled();
      boolean isDone();
      V get() throws InterputeredException,ExecutionExeception;
      V get(long timeout ,TimeUnit unit)throws InterputeredException,ExecutionExeception,TimeoutExeception;
    }
    public interface RunnableFuture<V> implements Runnable,Future<V>{
      void run();
    }
    

    这里的FutureTask间接实现了两个接口,在FutureTask的构造方法传入Callable或者是Runnable,而Runnable会转为Callable,runnable通过runnableadapter转为callable。同时FutureTask还具备Future的所有方法。

    举个例子

    Callable<Integer> callable=new Callable<Integer>(){
      public Ingeter call() throws Exception{
        return 100;
      }
    };
    FutureTask<Integer> task=new FutureTask<Integer>(callable);
    new Thread(task).start();
    
    task.get();//当然要先启动线程才能得到结果;
    

    这里的callable当成runnable用了。

    总结

    1. Callable比Runnable高级能返回结果值和抛出异常

    2. 可以有上述例子看到Callable来产生结果,Futuretask来获取结果。

    3. 在获取结果期间还可以控制是否取消thread 判断thread是否完成。

    4. FutureTask调用get方法获取call返回值过程中,主线程会阻塞,直到call方法结束并且返回。

    相关文章

      网友评论

        本文标题:Android十八章:Java线程中的Runnable,Call

        本文链接:https://www.haomeiwen.com/subject/bsrqwttx.html