Callable interface resolution

1. Definition of the interface:

public interface Callable<V>   
{   
    V call() throws Exception;   
} 
  • 1
  • 2
  • 3
  • 4

2. Similarities and differences between Callable and Runnable

First look at the definition of the Runnable interface

public interface Runnable {
    public abstract void run();
}
  • 1
  • 2
  • 3

The call() method of Callable is similar to the run() method in the Runnable interface. Both define the work to be done by the task. When implementing these two interfaces, these two methods need to be rewritten respectively. The main difference is that the call() method is If there is a return value (in fact, there are some differences, for example, the call method can throw an exception, but the run method cannot), running the Callable task can get a Future object, which represents the result of the asynchronous calculation. It provides methods to check whether a computation is complete, wait for the computation to complete, and retrieve the result of the computation. Through the Future object, you can understand the execution of the task, cancel the execution of the task, and obtain the execution result.

3. Tasks of type Callable can be executed in two ways:

We first define a Callable task MyCallableTask:

class MyCallableTask implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

①The 
FutureTask class implements two interfaces at the same time, Future and Runnable interfaces, so it can be executed by the thread as a Runnable, and can also be used as a Future to get the return value of Callable.

The general process performed with FutureTask is:

Callable<Integer> mycallabletask = new MyCallableTask();  
FutureTask<Integer> futuretask= new FutureTask<Integer>(mycallabletask);  
new Thread(futuretask).start();
  • 1
  • 2
  • 3

The running result of MyCallableTask's call() can be obtained through futuretask: 
futuretask.get(); ②Use 
the thread pool to run 
the prototype of the Callable task in the thread pool. For example:

public interface ExecutorService extends Executor {

  //提交一个Callable任务,返回值为一个Future类型
  <T> Future<T> submit(Callable<T> task);

  //other methods...
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

The general process for running Callable tasks with the help of a thread pool is:

  ExecutorService exec = Executors.newCachedThreadPool();
  Future<Integer> future = exec.submit(new MyCallableTask());
  • 1
  • 2

You can get the running result of MyCallableTask's call() through future: 
future.get(); 
I saw several good code examples on the Internet: 
a.Callable task runs with FutureTask:

public class CallableAndFutureTask {
    public static void main(String[] args) {
        Callable<Integer> callable = new Callable<Integer>() {
            public Integer call() throws Exception {
                return new Random().nextInt(100);
            }
        };
        FutureTask<Integer> future = new FutureTask<Integer>(callable);
        new Thread(future).start();
        try {
            Thread.sleep(5000);
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

b.Callable任务和线程池一起使用,然后返回值是Future:

public class CallableAndFuture {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        Future<Integer> future = threadPool.submit(new Callable<Integer>() {
            public Integer call() throws Exception {
                return new Random().nextInt(100);
            }
        });
        try {
            Thread.sleep(5000);// 可能做一些事情
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

以上a,b例子摘自(http://blog.csdn.net/ghsau/article/details/7451464
c.当执行多个Callable任务,有多个返回值时,我们可以创建一个Future的集合,例如:

class MyCallableTask implements Callable<String> {
    private int id;  
    public OneTask(int id){  
        this.id = id;  
    }  
    @Override  
    public String call() throws Exception {  
        for(int i = 0;i<5;i++){
            System.out.println("Thread"+ id);  
            Thread.sleep(1000); 
        }  
        return "Result of callable: "+id;  
    }   
}
public class Test {   

    public static void main(String[] args) {  
        //Callable<String> mycallabletask = new MyCallableTask(1);  
        ExecutorService exec = Executors.newCachedThreadPool();    
        ArrayList<Future<String>> results = new ArrayList<Future<String>>();      

        for (int i = 0; i < 5; i++) {    
            results.add(exec.submit(new MyCallableTask(i)));    
        }    

        for (Future<String> fs : results) {    
            if (fs.isDone()) {    
                try {  
                    System.out.println(fs.get());   
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            } else {    
                System.out.println("MyCallableTask任务未完成!");    
            }    
        }    
        exec.shutdown();  
    }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

那么引入Callable接口具有哪些好处呢? 
①可以获得任务执行返回值; 
②通过与Future的结合,可以实现利用Future来跟踪异步计算的结果。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324701452&siteId=291194637