Home  >  Article  >  Java  >  java-concurrency-Callable, Future and FutureTask

java-concurrency-Callable, Future and FutureTask

黄舟
黄舟Original
2017-01-19 11:56:261429browse

There are two ways to create a thread, one is to directly inherit Thread, and the other is to implement the Runnable interface

Difference: The interface can implement multiple inheritance

The defect is: after executing the task The execution result cannot be obtained afterwards

Callable and Runnable

java.lang.Runnable

[code]public interface Runnable {
    public abstract void run();
}

Because the return value of the run() method is void type, it cannot be obtained after the task is executed. Return no results.

java.util.concurren

[code]public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Generic interface, the type returned by the call() function is the V type passed in

Generally used in conjunction with ExecutorService , several overloaded versions of the submit method are declared in the ExecutorService interface

[code]<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);

Future

Future is to cancel the execution result of a specific Runnable or Callable task, query whether it is completed, and obtain the result . If necessary, you can obtain the execution result through the get method. This method will block until the task returns the result.

[code]public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

The cancel method is used to cancel the task. If the task cancellation is successful, it returns true. If the task cancellation fails, it returns false. The parameter mayInterruptIfRunning indicates whether it is allowed to cancel tasks that are being executed but have not been completed. If set to true, it means that tasks in the process of execution can be canceled. If the task has been completed, whether mayInterruptIfRunning is true or false, this method will definitely return false, that is, if the completed task is canceled, it will return false; if the task is being executed, if mayInterruptIfRunning is set to true, it will return true, if mayInterruptIfRunning is set to false , then return false; if the task has not been executed, then whether mayInterruptIfRunning is true or false, it will definitely return true.

The isCancelled method indicates whether the task was successfully canceled. If the task is successfully canceled before the task is completed normally, it returns true.

The isDone method indicates whether the task has been completed. If the task is completed, it returns true;

The get() method is used to obtain the execution result. This method will cause blocking and will wait until the task is completed. before returning;

get(long timeout, TimeUnit unit) is used to obtain the execution result. If the result is not obtained within the specified time, null will be returned directly.

In other words, Future provides three functions:

1) Determine whether the task is completed;

2) Ability to interrupt the task;

3) Ability to Get task execution results.

Because Future is just an interface, it cannot be used directly to create objects, so there is the following FutureTask.

FutureTask

[code]public class FutureTask<V> implements RunnableFuture<V>
[code]public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}
[code]public FutureTask(Callable<V> callable) {
}
public FutureTask(Runnable runnable, V result) {
}

In fact, FutureTask is the only implementation class of the Future interface.

Example

[code]public class Test {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        Future<Integer> result = executor.submit(task);
        executor.shutdown();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果"+result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}
class Task 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;
    }
}
[code]public class Test {
    public static void main(String[] args) {
        //第一种方式
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        executor.submit(futureTask);
        executor.shutdown();

        //第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread
        /*Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        Thread thread = new Thread(futureTask);
        thread.start();*/

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果"+futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}
class Task 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;
    }
}

If you use Future for cancelability but do not provide usable results, you can declare Future

The above is java-concurrency-Callable , Future and FutureTask content, please pay attention to the PHP Chinese website (m.sbmmt.com) for more related content!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn