`
woodding2008
  • 浏览: 289574 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Callable、FutureTask和Future

 
阅读更多

Callable是比Runnable更好的一个抽象,它有泛型的返回,也可以抛出异常。

/**
 * A task that returns a result and may throw an exception.
 * Implementors define a single method with no arguments called
 * {@code call}.
 *
 * <p>The {@code Callable} interface is similar to {@link
 * java.lang.Runnable}, in that both are designed for classes whose
 * instances are potentially executed by another thread.  A
 * {@code Runnable}, however, does not return a result and cannot
 * throw a checked exception.
 *
 * <p>The {@link Executors} class contains utility methods to
 * convert from other common forms to {@code Callable} classes.
 *
 * @see Executor
 * @since 1.5
 * @author Doug Lea
 * @param <V> the result type of method {@code call}
 */
@FunctionalInterface
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;
}

 

Feture为异步计算结果提供了以及执行状态提供了丰富的方法,使用Runnable时这部分工作需要额外处理。

public interface Future<V> {

    /**
     * Attempts to cancel execution of this task.  This attempt will
     * fail if the task has already completed, has already been cancelled,
     * or could not be cancelled for some other reason. If successful,
     * and this task has not started when {@code cancel} is called,
     * this task should never run.  If the task has already started,
     * then the {@code mayInterruptIfRunning} parameter determines
     * whether the thread executing this task should be interrupted in
     * an attempt to stop the task.
     *
     * <p>After this method returns, subsequent calls to {@link #isDone} will
     * always return {@code true}.  Subsequent calls to {@link #isCancelled}
     * will always return {@code true} if this method returned {@code true}.
     *
     * @param mayInterruptIfRunning {@code true} if the thread executing this
     * task should be interrupted; otherwise, in-progress tasks are allowed
     * to complete
     * @return {@code false} if the task could not be cancelled,
     * typically because it has already completed normally;
     * {@code true} otherwise
     */
    boolean cancel(boolean mayInterruptIfRunning);

    /**
     * Returns {@code true} if this task was cancelled before it completed
     * normally.
     *
     * @return {@code true} if this task was cancelled before it completed
     */
    boolean isCancelled();

    /**
     * Returns {@code true} if this task completed.
     *
     * Completion may be due to normal termination, an exception, or
     * cancellation -- in all of these cases, this method will return
     * {@code true}.
     *
     * @return {@code true} if this task completed
     */
    boolean isDone();

    /**
     * Waits if necessary for the computation to complete, and then
     * retrieves its result.
     *
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     */
    V get() throws InterruptedException, ExecutionException;

    /**
     * Waits if necessary for at most the given time for the computation
     * to complete, and then retrieves its result, if available.
     *
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     * @throws TimeoutException if the wait timed out
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

 

玩具代码

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//在执行器中取消任务
public class CancelTask {
	
	public static class Task implements Callable<String>{
		
		@Override
		public String call() throws Exception{
			while(true){
				System.out.printf("Task: Test\n");
				//通过中断异常退出,不能捕获中断异常
				Thread.sleep(100);
			}
		}
	}
	
	
	public static void main(String[] args) {
		
		ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newCachedThreadPool();
		Task task = new Task();
		System.out.printf("Main:Executing the Task \n");
		Future<String> result = executor.submit(task);
		
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.printf("Main: Canceling the Task \n");
		//true会立刻发送中断信号,false如果没有运行会停止,否则会执行完成
		result.cancel(true);
		
		System.out.printf("Main: Cancelled: %s \n", result.isCancelled());
		System.out.printf("Main: Done: %s\n", result.isDone());
		executor.shutdown();
		
		System.out.printf("Main: The executor has finished\n");

	}

}

 

FutureTask

RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

 

public class FutureTask<V> implements RunnableFuture<V> {

}

/**
 * A {@link Future} that is {@link Runnable}. Successful execution of
 * the {@code run} method causes completion of the {@code Future}
 * and allows access to its results.
 * @see FutureTask
 * @see Executor
 * @since 1.6
 * @author Doug Lea
 * @param <V> The result type returned by this Future's {@code get} method
 */
public interface RunnableFuture<V> extends Runnable, Future<V> {
    /**
     * Sets this Future to the result of its computation
     * unless it has been cancelled.
     */
    void run();
}

 

玩具代码

 

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

//在执行器中控制任务的完成
public class ControlTaskFinished {

	public static class ExecutableTask implements Callable<String> {

		private String name;

		public String getName() {
			return name;
		}

		public ExecutableTask(String name) {
			this.name = name;
		}

		public String call() throws Exception {
			try {
				long duration = (long) (Math.random() * 10);
				System.out.printf("%s:Waiting %d seconds for results. \n",
						this.name, duration);
				TimeUnit.SECONDS.sleep(duration);
			} catch (InterruptedException e) {

			}
			return "Hello, world. I'm " + name;
		}
	}

	public static class ResultTask extends FutureTask<String> {
		private String name;

		public ResultTask(Callable<String> callable) {
			super(callable);
			this.name = ((ExecutableTask) callable).getName();
		}

		// 覆盖done方法【默认为空方法】
		protected void done() {
			if (isCancelled()) {
				System.out.printf("%s: Has been canceled\n", name);
			} else {
				System.out.printf("%s: Has finished\n", name);
			}
		}
	}

	public static void main(String[] args) {

		ExecutorService executor = (ExecutorService) Executors
				.newCachedThreadPool();
		ResultTask resultTask[] = new ResultTask[5];
		for (int i = 0; i < 5; i++) {
			ExecutableTask executableTask = new ExecutableTask("Task " + i);
			resultTask[i] = new ResultTask(executableTask);
			// RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。
			// 所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
			executor.submit(resultTask[i]);
		}

		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		for (int i = 0; i < resultTask.length; i++) {
			try {
				if (!resultTask[i].isCancelled()) {
					System.out.printf("%s \n", resultTask[i].get());
				}
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		}

		executor.shutdown();
	}

}

 

 

分享到:
评论

相关推荐

    Java使用Callable和Future创建线程操作示例

    Java使用Callable和Future创建线程操作示例主要介绍了Java使用Callable和Future创建线程操作,结合实例形式分析了java使用Callable接口和Future类创建线程的相关操作技巧与注意事项。 首先,Java 5开始,Java提供了...

    Java中的Runnable,Callable,Future,FutureTask的比较

    Java中的Runnable、Callable、Future和FutureTask是Java多线程编程中的核心概念,它们各自扮演着不同的角色,共同协作以实现并发任务的管理和执行。 1. **Runnable**: Runnable是最基本的多线程接口,它只有一个`...

    Runnable、Callable、Future、FutureTask有什么关联.docx

    Runnable、Callable、Future、FutureTask有什么关联.docx

    Android(Java)之多线程结果返回——Future 、FutureTask、Callable、Runnable

    `Future`、`FutureTask`、`Callable`和`Runnable`是Java并发编程中的核心接口和类,它们在Android开发中同样有着广泛的应用。下面将详细介绍这些概念以及它们如何协同工作。 1. `Runnable`: 这是Java中最基础的多...

    【并发编程】 — Runnable、Callable、Future和FutureTask之间的关系

    2 如何使用FutureTask 、Future、Callable、线程池实现线程2.1 FutureTask + Callable实现多线程2.2 线程池+Future+Callable 实现多线程3 Runnable、Callable、Future和FutureTask之间的关系3.1 整体关系介绍3.2 ...

    比较java中Future与FutureTask之间的关系

    在Java中,Future和FutureTask都是用于获取线程执行的返回结果,但是它们之间存在一些差异和关联。本文将详细介绍Future和FutureTask的关系、使用和分析。 一、Future介绍 Future位于java.util.concurrent包下,是...

    Callable, Future, FutureTask2

    通过合规策略对服务器进行监控,确保服务器的运行、帐号在服务器上的操作符合预设的规则...进程:监控服务器上的进程,并对某些进程、目录、文件进行标识和监控,只允许指定的进程对指定目录下的指定格式文件执行写操作

    Callable,Future的使用方式

    Callable,Future的使用方式,里面使用了三种使用方式分别是FutureTask,ExecutorService,ExecutorCompletionService

    Callable和Future.doc

    Callable 和 Future 是 Java 多线程编程中两个重要的接口,它们在处理异步计算和结果获取方面发挥着关键作用。Callable 与 Runnable 相似,但具有更强大的功能,允许任务返回结果并处理异常。 Callable 接口: ...

    Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    在Java多线程编程中,CyclicBarrier、Callable、Future和FutureTask是四个重要的组件,它们各自提供了不同的功能,帮助开发者更好地管理和协调并发任务。接下来,我们将深入探讨这些组件的特性和使用方法。 首先,...

    FutureTask学习

    `FutureTask`作为`Runnable`和`Callable`的桥梁,允许我们将一个`Callable`任务提交给`Executor`执行,并在后续代码中通过`FutureTask`的API查询任务状态,获取结果或取消任务。下面将详细介绍`FutureTask`的主要...

    Java中Future、FutureTask原理以及与线程池的搭配使用

    Java中的`Future`和`FutureTask`是并发编程中重要的工具,它们允许程序异步执行任务并获取结果。`Future`接口提供了对异步计算结果的访问和控制,而`FutureTask`是`Future`的一个具体实现,它还同时实现了`Runnable`...

    浅谈在Java中使用Callable、Future进行并行编程

    从Java 1.5开始,引入了Callable和Future接口,为并行编程提供了一种更为高效和便捷的解决方案。 Callable接口是Java并发库中的一个关键接口,位于`java.util.concurrent`包下。Callable接口与Runnable接口类似,但...

    Java concurrency线程池之Callable和Future_动力节点Java学院整理

    Java concurrency线程池之Callable和Future Java concurrency是一个重要的概念,在Java编程中,线程池是一个关键组件。今天,我们将详细介绍Java concurrency线程池之Callable和Future,这两个组件在Java并发编程中...

    JAVA中Callable的使用

    2. **Future和ExecutorService** 要执行Callable任务,我们需要使用`ExecutorService`,它是`java.util.concurrent`包中的一个接口,用于管理和控制线程的执行。首先,我们创建一个ExecutorService实例,然后通过`...

    揭密FutureTask.docx

    FutureTask继承自RunnableFuture接口,这是一个复合接口,由Future和Runnable组成。这意味着FutureTask既是可执行的任务,又可以等待其结果。这种设计允许FutureTask既可以直接提交给Thread执行,也可以通过...

    java多线程返回值使用示例(callable与futuretask)

    为了解决这个问题,Java提供了`Callable`接口和`FutureTask`类,它们是实现多线程返回值的关键工具。 `Callable`接口类似于`Runnable`,但比它功能更强大。`Callable`接口中的`call()`方法可以返回一个结果,并且...

    【Java】Callable创建线程用到的适配器模式(csdn)————程序.pdf

    在Java编程中,多线程是并发处理任务的关键机制,Callable接口和FutureTask类是Java提供的用于创建具有返回值的线程的重要工具。本文将详细解释Callable接口的使用、适配器模式在创建线程中的应用,以及FutureTask在...

    spring线程池ThreadPoolExecutor配置以及FutureTask的使用

    Future&lt;Integer&gt; future = executor.submit(callable); // 可以进行其他操作 try { int computedResult = future.get(); // 获取计算结果,会阻塞直到任务完成 System.out.println("Computed result: " + ...

    java多线程编程同步器Future和FutureTask解析及代码示例

    Java多线程编程中,`Future` 和 `FutureTask` 是两种重要的同步工具,它们用于管理异步计算的结果。在Java并发编程中,通常我们会使用`ExecutorService`来提交任务,而`Future`和`FutureTask`就是与这些任务交互的...

Global site tag (gtag.js) - Google Analytics