What is callable in Java?

2019-05-03 12:10发布

问题:

The title pretty much sums it.

I want to know the concept and idea of callable . I have read a question here on difference between callable and runnable. but no one show code and give detail what a callable is. I don't want to know the difference between them. I want to know ,

  1. What is a callable ?

  2. When to use them and how to use them .

  3. When they come in action for Android.

回答1:

You can check this example:

In this example Callable task returns the name of thread executing the task after one second. We are using Executor framework to execute 100 tasks in parallel and use Future to get the result of the submitted tasks.

package com.journaldev.threads;

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 MyCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        Thread.sleep(1000);
        //return the thread name executing this callable task
        return Thread.currentThread().getName();
    }

    public static void main(String args[]){
        //Get ExecutorService from Executors utility class, thread pool size is 10
        ExecutorService executor = Executors.newFixedThreadPool(10);
        //create a list to hold the Future object associated with Callable
        List<Future<String>> list = new ArrayList<Future<String>>();
        //Create MyCallable instance
        Callable<String> callable = new MyCallable();
        for(int i=0; i< 100; i++){
            //submit Callable tasks to be executed by thread pool
            Future<String> future = executor.submit(callable);
            //add Future to the list, we can get return value using Future
            list.add(future);
        }
        for(Future<String> fut : list){
            try {
                //print the return value of Future, notice the output delay in console
                // because Future.get() waits for task to get completed
                System.out.println(new Date()+ "::"+fut.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        //shut down the executor service now
        executor.shutdown();
    }

}

You may also check Using Callable to Return Results From Runnables



回答2:

Callable is similar to Runnable but it returns a result and may throw an exception. Use them when you expect your asynchronous tasks to return result.

The returned result of asynchronous computation is represented by a Future.

You can check this simple example implemented using FutureTask (which implements RunnableFuture and Future)

public static void main(String[] args) {

    // providing an anonymous callable to FutureTask
    RunnableFuture<String> future = new FutureTask<String>(
            new Callable<String>() {
                @Override
                public String call() throws InterruptedException {
                    System.out.println("sleeping");
                    Thread.sleep(2000);
                    System.out.println("returning");
                    return "hello-world";
                }

            });

    Thread t = new Thread(future);
    t.start();

    try {
        // the get Waits if necessary for the computation to complete
        System.out.println(future.get());
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

}