zoukankan      html  css  js  c++  java
  • JAVA-Runnable、Callable、FutureTask

    通常,创建线程的执行单元有两种,一种是直接继承 Thread,另外一种就是实现 Runnable 接口。

    但这两种都有一个问题就是无法有返回值,且子线程在执行过程中无法抛出异常。想线程有返回值,可以使用 Callable 来创建执行单元。

    Runnable

    一个接口,没有返回值

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

    Callable

    一个接口,有返回值,且允许抛出异常

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

    FutureTask

    Future 接口的实现类,用于包装 Runnable 或 Callable,用于获得线程的执行结果,且允许中断线程执行过程,还可用于判断线程是否执行完成

    /**
     * boolean isCancelled()
     * 任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
     *
     * V get()
     * 获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回
     *
     * V get(long timeout, TimeUnit unit)
     * 在指定时间内尝试获取执行结果。若超时则抛出超时异常
     *
     * Boolean isDone()
     * 任务是否已经完成(包括正常执行完毕、执行异常或者任务取消),若任务完成,则返回 true
     *
     * boolean cancel(boolean mayInterruptInRunning)
     * 取消任务,如果取消任务成功则返回 true,如果取消任务失败则返回 false
     * 参数 mayInterruptIfRunning 表示是否允许取消正在执行却没有执行完毕的任务,如果设置 true,则表示可以取消正在执行过程中的任务
     * 如果任务已经完成,则无论 mayInterruptIfRunning 为 true 还是 false,此方法肯定返回 false,即如果取消已经完成的任务会返回 false
     * 如果任务正在执行,若 mayInterruptIfRunning 设置为 true,则返回 true,若 mayInterruptIfRunning 设置为 false,则返回 false
     * 如果任务还没有执行,则无论 mayInterruptIfRunning 为 true 还是 false,肯定返回 true
     */

    线程池中的 (java.util.concurrent.AbstractExecutorService)submit 方法,将任务包装成 RunnableFuture 再执行

    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }
    
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }
    
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
    View Code

    使用示例

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    };
    // 无返回值
    FutureTask<?> rFutureTask = new FutureTask<Void>(runnable, null);
    // 返回指定值
    // FutureTask<String> rFutureTask = new FutureTask<String>(runnable, "OK");
    System.out.println(rFutureTask.isDone());
    new Thread(rFutureTask).start();
    
    
    Callable<String> callable = new Callable<String>() {
        @Override
        public String call() throws Exception {
            Thread.sleep(1000);
            return Thread.currentThread().getName();
        }
    };
    FutureTask<String> cFutureTask = new FutureTask(callable);
    new Thread(cFutureTask).start();
    System.out.println(cFutureTask.isCancelled());
    // 获取结果
    System.out.println(cFutureTask.get());

    https://www.cnblogs.com/dolphin0520/p/3949310.html

    https://www.cnblogs.com/maypattis/p/5827671.html

  • 相关阅读:
    HTML5表单
    jQuery Mobile组件
    HTML5新增加的功能
    jQuery Mobile基础
    【android】两个按钮的宽度各占屏幕的一半
    AndroidUI--SlidingMenu使用例子
    android之PackageManager简介
    AlarmManager类的应用
    AlarmManager类的应用(实现闹钟功能)
    laravel 控制器内使用切换数据库
  • 原文地址:https://www.cnblogs.com/jhxxb/p/10857660.html
Copyright © 2011-2022 走看看