精华内容
下载资源
问答
  • Future

    2020-05-16 13:38:58
    Dart下的Future类似于ES6下新增的Promise,也是为了解决异步回调带来的各种问题。 构造函数 Future(FutureOr<T> computation()) computation 的返回值可以是普通值或者是Future对象 Future<num> ...

    Dart下的Future类似于ES6下新增的Promise,也是为了解决异步回调带来的各种问题。

    构造函数

    Future(FutureOr<T> computation())

    computation 的返回值可以是普通值或者是Future对象

    Future<num> future1 = Future((){
        print('async call1');
        return 123;
    });
    
    Future<Future> future2 = Future((){
        print('async call2');
        return future1;
    });
    
    

    Dart

    需要注意的是,computation函数体中的代码是被异步执行的,这与Promise构造函数的回调执行时机是不一样的,如需要被同步执行,则使用如下这个命名构造函数:

    Future.sync(FutureOr<T> computation())

    Future<num> future = Future.sync((){
        print('sync call');
        return 123;
    });
    

    Dart

    Future.delayed(Duration duration, [ FutureOr<T> computation() ])

    延时后再执行computation

    Future.delayed(Duration(seconds: 1), () {
        print("print after 1 second");
    });
    

    Dart

    Future.value([FutureOr<T> value ])

    创建一个future对象,以value完成

    Future.value(123);
    

    Dart

    Future.error(Object error, [ StackTrace stackTrace ])

    创建一个future对象,以错误状态完成

    Future.error('some error');
    

    Dart

    Future.microtask(FutureOr<T> computation())

    dart下的异步任务队列有两个:event queuemicrotask queuemicrotask queue的优先级更高,而future的任务默认是属于event queue。上面这个构造函数就可以创建属于microtask queue的future。

    Future.microtask(()=>print("microtask"));
    

    Dart

    实例方法

    then<R>(FutureOr<R> onValue(T value), { Function onError }) → Future<R>

    行为与ES6中Promise.prototype.then几乎一致

    Future.val(123).then((val)=>print(val));
    
    Future.error("some error").then((val) {},{onError: (err) => print(err)});
    

    Dart

    catchError(Function onError, { bool test(Object error) }) → Future<T>

    处理future中的异常,第二个参数不使用的情况下,与ES6中的Promise.prototype.catch一致

    Future.error("some error").catchError((err) => print(err));
    

    Dart

    第二个参数提供的情况下,必须返回true,回调函数才能正常捕获错误。暂没想到该参数有什么用。

    asStream() → Stream<T>

    创建流,该流包含future中的值或错误

    timeout(Duration timeLimit, { FutureOr<T> onTimeout() }) → Future<T>

    给future指定一个超时时间,若超时了执行onTimeout回调,并返回新的值作为下一个future的值

      Future.delayed(Duration(seconds: 2)).timeout(Duration(seconds: 1),
          onTimeout: () {
        print("timeout");
        return "TIME OUT";
      });
    

    Dart

    whenComplete(FutureOr action()) → Future<T>

    类似于ES7中的Promise.prototype.finally,无论future是正常完成还是产生异常都会执行

    Future.value("value").whenComplete(() {
        print('complete');
      })
    

    Dart

    静态方法

    any<T>(Iterable<Future<T>> futures) → Future<T>

    行为与ES6中Promise.race一致,若futures为空,则返回的future永远不会完成

    Future.any([
      Future.delayed(Duration(seconds: 1)).then((val) => 1),
      Future.delayed(Duration(seconds: 2)).then((val) => 2),
      Future.delayed(Duration(seconds: 3)).then((val) => 3),
    ]).then((val) {
      print(val); // val == 1
    });
    

    Dart

    doWhile(FutureOr<bool> action()) → Future

    do{}while()的异步版本

    var i = 0;
    Future.doWhile(() {
      print(i++);
      return Future.value(i < 10);
    }).then((val) => print('after doWhile'));
    

    Dart

    forEach<T>(Iterable<T> elements, FutureOr action(T element)) → Future

    异步forEach,future会一直等待elements遍历完毕才会变成完成状态,除非在遍历过程中出现错误

    Future.forEach([1, Future.delayed(Duration(seconds: 2)), 3], (val) {
      print(val);
      return val;
    }).then((val) => print('success=>>>$val'));
    

    Dart

    wait<T>(Iterable<Future<T>> futures, { bool eagerError: false, void cleanUp(T successValue) }) → Future<List<T>>

    eagerError参数未true的情况下,其行为与ES6中Promise.all基本一致

    Future.wait([
      Future.delayed(Duration(seconds: 1)).then((val) => 1),
      Future.delayed(Duration(seconds: 2)).then((val) => 2),
      Future.delayed(Duration(seconds: 3)).then((val) => 3),
    ]).then((val) => print(val));  // 3s后得到val 为 [1,2,3]
    

    Dart

    eagerError默认值为false,表明futures中任何一项执行出错都不会立即返回新的future,而是需要等待所有项都是完成状态才会返回。

    举例来讲,以下代码在eagerErrorfalse的情况下,需要经历3s才会输出err=>error,而设置eagerErrortrue,则只需要1.5s:

    Future.wait([
      Future.delayed(Duration(milliseconds: 1500))
          .then((val) => Future.error('error')),
      Future.delayed(Duration(seconds: 1)).then((val) => 1),
      Future.delayed(Duration(seconds: 2)).then((val) => 2),
      Future.delayed(Duration(seconds: 3)).then((val) => 3),
    ], eagerError: false)
        .then((val) => print('then=>$val'), onError: (err) => print('err=>$err'));
    

    Dart

    cleanUp在futures中某项出错的时候,会给每项正常执行的future提供清理操作,传递给cleanUp的参数为每个正常执行项的完成值,Future.await只会处理最先抛出的错误,但是整个程序会等待所有的future项完成才会结束。

    Future.wait([
      Future.delayed(Duration(milliseconds: 1500))
          .then((val) => Future.error('error')),
      Future.delayed(Duration(seconds: 1)).then((val) => 1),
      Future.delayed(Duration(seconds: 2)).then((val) => 2),
    ], cleanUp: (val) => print('complete=>${val}'))
        .then((val) => print('then=>$val'), onError: (err) => print('err=>$err'));
    

    Dart

    以上代码会在1.5s后依次输出:

    complete=>1
    complete=>2
    err=>error
    

    粗略过完了所有的API,应该还有很多细节遗漏的地方,特别是在内部任务调度这块,涉及到代码执行顺序的问题,需要在实际项目中去摸索、加深。

    展开全文
  • Java线程(七):Callable和Future

    万次阅读 多人点赞 2016-02-05 15:12:04
    接着上一篇继续并发包的学习,本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果。 Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回...

           接着上一篇继续并发包的学习,本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果。
           Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值,下面来看一个简单的例子:

    public class CallableAndFuture {
    	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();
    		}
    	}
    }
    

           FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到,岂不美哉!这里有一个Future模式的介绍:http://openhome.cc/Gossip/DesignPattern/FuturePattern.htm。
           下面来看另一种方式使用Callable和Future,通过ExecutorService的submit方法执行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();
    		}
    	}
    }
    

           代码是不是简化了很多,ExecutorService继承自Executor,它的目的是为我们管理Thread对象,从而简化并发编程,Executor使我们无需显示的去管理线程的生命周期,是JDK 5之后启动任务的首选方式。
           执行多个带返回值的任务,并取得多个返回值,代码如下:

    public class CallableAndFuture {
    	public static void main(String[] args) {
    		ExecutorService threadPool = Executors.newCachedThreadPool();
    		CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);
    		for(int i = 1; i < 5; i++) {
    			final int taskID = i;
    			cs.submit(new Callable<Integer>() {
    				public Integer call() throws Exception {
    					return taskID;
    				}
    			});
    		}
    		// 可能做一些事情
    		for(int i = 1; i < 5; i++) {
    			try {
    				System.out.println(cs.take().get());
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			} catch (ExecutionException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    } 
    

           其实也可以不使用CompletionService,可以先创建一个装Future类型的集合,用Executor提交的任务返回值添加到集合中,最后遍历集合取出数据,代码略。更新于2016-02-05,评论中就这个说法引发了讨论,其实是我没有讲清楚,抱歉。这里再阐述一下:提交到CompletionService中的Future是按照完成的顺序排列的,这种做法中Future是按照添加的顺序排列的。所以这两种方式的区别就像评论中fishjam**所描述的那样。

           本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7451464,转载请注明。

    展开全文
  • JAVA Future类详解

    万次阅读 多人点赞 2018-06-06 17:24:24
    在并发编程中,我们经常用到非阻塞的模型,在之前的多线程的三种实现中,不管是继承thread类还是实现runnable接口,都无法保证获取到之前的执行结果。通过实现Callback接口,并用Future可以来接收多线程的执行结果。

    1. Future的应用场景

            在并发编程中,我们经常用到非阻塞的模型,在之前的多线程的三种实现中,不管是继承thread类还是实现runnable接口,都无法保证获取到之前的执行结果。通过实现Callback接口,并用Future可以来接收多线程的执行结果。

            Future表示一个可能还没有完成的异步任务的结果,针对这个结果可以添加Callback以便在任务执行成功或失败后作出相应的操作。

            举个例子:比如去吃早点时,点了包子和凉菜,包子需要等3分钟,凉菜只需1分钟,如果是串行的一个执行,在吃上早点的时候需要等待4分钟,但是因为你在等包子的时候,可以同时准备凉菜,所以在准备凉菜的过程中,可以同时准备包子,这样只需要等待3分钟。那Future这种模式就是后面这种执行模式。

    2. Future的类图结构

            Future接口定义了主要的5个接口方法,有RunnableFuture和SchedualFuture继承这个接口,以及CompleteFuture和ForkJoinTask继承这个接口。

    RunnableFuture

            这个接口同时继承Future接口和Runnable接口,在成功执行run()方法后,可以通过Future访问执行结果。这个接口都实现类是FutureTask,一个可取消的异步计算,这个类提供了Future的基本实现,后面我们的demo也是用这个类实现,它实现了启动和取消一个计算,查询这个计算是否已完成,恢复计算结果。计算的结果只能在计算已经完成的情况下恢复。如果计算没有完成,get方法会阻塞,一旦计算完成,这个计算将不能被重启和取消,除非调用runAndReset方法。

            FutureTask能用来包装一个Callable或Runnable对象,因为它实现了Runnable接口,而且它能被传递到Executor进行执行。为了提供单例类,这个类在创建自定义的工作类时提供了protected构造函数。

    SchedualFuture

            这个接口表示一个延时的行为可以被取消。通常一个安排好的future是定时任务SchedualedExecutorService的结果

    CompleteFuture

            一个Future类是显示的完成,而且能被用作一个完成等级,通过它的完成触发支持的依赖函数和行为。当两个或多个线程要执行完成或取消操作时,只有一个能够成功。

    ForkJoinTask

            基于任务的抽象类,可以通过ForkJoinPool来执行。一个ForkJoinTask是类似于线程实体,但是相对于线程实体是轻量级的。大量的任务和子任务会被ForkJoinPool池中的真实线程挂起来,以某些使用限制为代价。

    3. Future的主要方法

    Future接口主要包括5个方法

    get()方法可以当任务结束后返回一个结果,如果调用时,工作还没有结束,则会阻塞线程,直到任务执行完毕

    get(long timeout,TimeUnit unit)做多等待timeout的时间就会返回结果

    cancel(boolean mayInterruptIfRunning)方法可以用来停止一个任务,如果任务可以停止(通过mayInterruptIfRunning来进行判断),则可以返回true,如果任务已经完成或者已经停止,或者这个任务无法停止,则会返回false.

    isDone()方法判断当前方法是否完成

    isCancel()方法判断当前方法是否取消

    4. Future示例demo

    需求场景:等早餐过程中,包子需要3秒,凉菜需要1秒,普通的多线程需要四秒才能完成。先等凉菜,再等包子,因为等凉菜时,普通多线程启动start()方法,执行run()中具体方法时,没有返回结果,所以如果要等有返回结果,必须是要1秒结束后才知道结果。

    普通多线程:

    public class BumThread extends Thread{
    	
    	@Override
    	public void run() {
    		try {
    			Thread.sleep(1000*3);
    			System.out.println("包子准备完毕");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    public class ColdDishThread extends Thread{
    	
    	@Override
    	public void run() {
    		try {
    			Thread.sleep(1000);
    			System.out.println("凉菜准备完毕");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    	public static void main(String[] args) throws InterruptedException {
    		long start = System.currentTimeMillis();
    		
    		// 等凉菜 -- 必须要等待返回的结果,所以要调用join方法
    		Thread t1 = new ColdDishThread();
    		t1.start();
    		t1.join();
    		
    		// 等包子 -- 必须要等待返回的结果,所以要调用join方法
    		Thread t2 = new BumThread();
    		t2.start();
    		t2.join();
    		
    		long end = System.currentTimeMillis();
    		System.out.println("准备完毕时间:"+(end-start));
    	}

    采用Future模式:

    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		long start = System.currentTimeMillis();
    		
    		// 等凉菜 
    		Callable ca1 = new Callable(){
    
    			@Override
    			public String call() throws Exception {
    				try {
    					Thread.sleep(1000);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				return "凉菜准备完毕";
    			}
    		};
    		FutureTask<String> ft1 = new FutureTask<String>(ca1);
    		new Thread(ft1).start();
    		
    		// 等包子 -- 必须要等待返回的结果,所以要调用join方法
    		Callable ca2 = new Callable(){
    
    				@Override
    				public Object call() throws Exception {
    					try {
    						Thread.sleep(1000*3);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					return "包子准备完毕";
    			}
    		};
    		FutureTask<String> ft2 = new FutureTask<String>(ca2);
    		new Thread(ft2).start();
    		
    		System.out.println(ft1.get());
    		System.out.println(ft2.get());
    		
    		long end = System.currentTimeMillis();
    		System.out.println("准备完毕时间:"+(end-start));
    	}

    参考:

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

    展开全文
  • Future接口介绍: 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现。 Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是...

    原文地址:https://blog.csdn.net/devinteng/article/details/23455733

    Future接口介绍:

    在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现。 Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是Java线程Future模式的实现,可以来进行异步计算。

    Future模式可以这样来描述:我有一个任务,提交给了Future,Future替我完成这个任务。期间我自己可以去做任何想做的事情。一段时间之后,我就便可以从Future那儿取出结果。就相当于下了一张订货单,一段时间后可以拿着提订单来提货,这期间可以干别的任何事情。其中Future 接口就是订货单,真正处理订单的是Executor类,它根据Future接口的要求来生产产品。

    Future接口提供方法来检测任务是否被执行完,等待任务执行完获得结果,也可以设置任务执行的超时时间。这个设置超时的方法就是实现Java程序执行超时的关键。

    Future接口是一个泛型接口,严格的格式应该是Future<V>,其中V代表了Future执行的任务返回值的类型。 Future接口的方法介绍如下:

    boolean cancel (boolean mayInterruptIfRunning) 取消任务的执行。参数指定是否立即中断任务执行,或者等等任务结束
    boolean isCancelled () 任务是否已经取消,任务正常完成前将其取消,则返回 true
    boolean isDone () 任务是否已经完成。需要注意的是如果任务正常终止、异常或取消,都将返回true
    V get () throws InterruptedException, ExecutionException  等待任务执行结束,然后获得V类型的结果。InterruptedException 线程被中断异常, ExecutionException任务执行异常,如果任务被取消,还会抛出CancellationException
    V get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 同上面的get功能一样,多了设置超时时间。参数timeout指定超时时间,uint指定时间的单位,在枚举类TimeUnit中有相关的定义。如果计算超时,将抛出TimeoutException

    Future的实现类有java.util.concurrent.FutureTask<V>即 javax.swing.SwingWorker<T,V>。通常使用FutureTask来处理我们的任务。FutureTask类同时又实现了Runnable接口,所以可以直接提交给Executor执行。使用FutureTask实现超时执行的代码如下:

    <span style="font-size:18px;">ExecutorService executor = Executors.newSingleThreadExecutor();
    FutureTask<String> future =
           new FutureTask<String>(new Callable<String>() {//使用Callable接口作为构造参数
             public String call() {
               //真正的任务在这里执行,这里的返回值类型为String,可以为任意类型
           }});
    executor.execute(future);
    //在这里可以做别的任何事情
    try {
    	result = future.get(5000, TimeUnit.MILLISECONDS); //取得结果,同时设置超时执行时间为5秒。同样可以用future.get(),不设置执行超时时间取得结果
    } catch (InterruptedException e) {
    	futureTask.cancel(true);
    } catch (ExecutionException e) {
    	futureTask.cancel(true);
    } catch (TimeoutException e) {
    	futureTask.cancel(true);
    } finally {
    	executor.shutdown();
    }</span>
    

    不直接构造Future对象,也可以使用ExecutorService.submit方法来获得Future对象,submit方法即支持以 Callable接口类型,也支持Runnable接口作为参数,具有很大的灵活性。使用示例如下:

    <span style="font-size:18px;">ExecutorService executor = Executors.newSingleThreadExecutor();
    FutureTask<String> future = executor.submit(
       new Callable<String>() {//使用Callable接口作为构造参数
           public String call() {
          //真正的任务在这里执行,这里的返回值类型为String,可以为任意类型
       }});
    //在这里可以做别的任何事情
    //同上面取得结果的代码</span>
    

    Future模式:

    什么是future:future的原理是当你申请资源(计算资源或I/O资源)时,立即返回一个虚拟的资源句柄,当真正使用的时候,再将虚拟的句柄转化成真正的资源,相当于预获取。

    Future使用方法伪代码如下:        

        Future::Future(Job_func):
    
            Thread.run(Job_func);
    
        End
    
        Future::get_result():
    
            While(result == NULL):
    
            Thread.sleep()
    
            Return result
        End

    Future模式只有在并行运算的框架内才有意义。当一个逻辑操作设计的耗时操作比较多时,可以将耗时操作拆分成多个不太耗时的子操作,使子操作并行的执行,逻辑层依次获取子操作的结果。架设我们要执行一个逻辑操作,要求执行一次mysql查询,还要读一次文件,如果使用普通的同步方式:

        Do:
    
        query = Mysql_query()
    
        file = File_read()
    
            Do_thing(query, file)
    
        Done

    使用future模式示例如下:

        Do:
    
            Future a(Mysql_query)//! 非阻塞
    
            Future b(File_read) //! 非阻塞
    
            Query = a.get_result() //! 阻塞获取结果
    
            File = b.get_result() //! 阻塞获取结果
    
            Do_thing(query, file)
    
        Done

    这样sql查询和读取文件实现了并行运行,同步等待的时间为二者开销较大的运行时间。

    适于使用future模式的时机:在客户端,我们常常需要阻塞的获取结果,通过future模式可以大大提高响应速度。而在服务端程序,阻塞操作会降低系统的吞吐量,future模式试用的范围较窄,一般服务端采用异步回调的方式,将耗时的操作并行化,再通过回调方式将结果合并。Future构造时生成了虚拟的结果,如果使用这个结果越晚,当get_result时越不容易阻塞,所以从生成future到获取结果的间隔越长,future模式的功效越大。

    android中SafeAsyncTask异步操作类中使用:

    /**
     * 使用JUC实现的异步任务处理类,该类实现异步任务处理外,还另外定义线程中断和捕捉异常声明周期方法
     * 使用限制: 不能处理任务进度
     *
     * @param <ResultT>
     */
    public abstract class SafeAsyncTask<ResultT> implements Callable<ResultT> {
        public static final int DEFAULT_POOL_SIZE = Runtime.getRuntime().availableProcessors() << 1;
        protected static final Executor DEFAULT_EXECUTOR = Executors.newFixedThreadPool(DEFAULT_POOL_SIZE);
     
        protected Handler handler;
        protected Executor executor;
        protected StackTraceElement[] launchLocation;
        protected FutureTask<Void> future;
     
     
        /**
         * Sets executor to Executors.newFixedThreadPool(DEFAULT_POOL_SIZE) and
         * Handler to new Handler()
         */
        public SafeAsyncTask() {
            this.executor = DEFAULT_EXECUTOR;
        }
     
        /**
         * Sets executor to Executors.newFixedThreadPool(DEFAULT_POOL_SIZE)
         */
        public SafeAsyncTask( Handler handler ) {
            this.handler = handler;
            this.executor = DEFAULT_EXECUTOR;
        }
     
        /**
         * Sets Handler to new Handler()
         */
        public SafeAsyncTask( Executor executor ) {
            this.executor = executor;
        }
     
        public SafeAsyncTask( Handler handler, Executor executor ) {
            this.handler = handler;
            this.executor = executor;
        }
     
     
        public FutureTask<Void> future() {
            future = new FutureTask<Void>( newTask() );
            return future;
        }
     
        public SafeAsyncTask<ResultT> executor( Executor executor ) {
            this.executor = executor;
            return this;
        }
     
        public Executor executor() {
            return executor;
        }
     
        public SafeAsyncTask<ResultT> handler( Handler handler ) {
            this.handler = handler;
            return this;
        }
     
        public Handler handler() {
            return handler;
        }
     
        public void execute() {
            execute(Thread.currentThread().getStackTrace());
        }
     
        protected void execute( StackTraceElement[] launchLocation ) {
            this.launchLocation = launchLocation;
            executor.execute( future() );
        }
     
        public boolean cancel( boolean mayInterruptIfRunning ) {
            if( future==null )
                throw new UnsupportedOperationException("You cannot cancel this task before calling future()");
     
            return future.cancel(mayInterruptIfRunning);
        }
     
     
        /**
         * @throws Exception, captured on passed to onException() if present.
         */
        protected void onPreExecute() throws Exception {}
     
        /**
         * @param t the result of {@link #call()}
         * @throws Exception, captured on passed to onException() if present.
         */
        @SuppressWarnings({"UnusedDeclaration"})
        protected void onSuccess( ResultT t ) throws Exception {}
     
        /**
         * Called when the thread has been interrupted, likely because
         * the task was canceled.
         *
         * By default, calls {@link #onException(Exception)}, but this method
         * may be overridden to handle interruptions differently than other
         * exceptions.
         *
         * @param e an InterruptedException or InterruptedIOException
         */
        protected void onInterrupted( Exception e ) {
            onException(e);
        }
     
        /**
         * Logs the exception as an Error by default, but this method may
         * be overridden by subclasses.
         *
         * @param e the exception thrown from {@link #onPreExecute()}, {@link #call()}, or {@link #onSuccess(Object)}
         * @throws RuntimeException, ignored
         */
        protected void onException( Exception e ) throws RuntimeException {
            onThrowable(e);
        }
     
        protected void onThrowable( Throwable t ) throws RuntimeException {
            Ln.e(t, "Throwable caught during background processing");
        }
     
        /**
         * @throws RuntimeException, ignored
         */
        protected void onFinally() throws RuntimeException {}
     
     
        protected Task<ResultT> newTask() {
            return new Task<ResultT>(this);
        }
     
     
        public static class Task<ResultT> implements Callable<Void> {
            protected SafeAsyncTask<ResultT> parent;
            protected Handler handler;
     
            public Task(SafeAsyncTask<ResultT> parent) {
                this.parent = parent;
                this.handler = parent.handler!=null ? parent.handler : new Handler(Looper.getMainLooper());
            }
     
            public Void call() throws Exception {
                try {
                    doPreExecute();
                    doSuccess(doCall());
     
                } catch( final Exception e ) {
                    try {
                        doException(e);
                    } catch( Exception f ) {
                        // logged but ignored
                        Ln.e(f);
                    }
     
                } catch( final Throwable t ) {
                    try {
                        doThrowable(t);
                    } catch( Exception f ) {
                        // logged but ignored
                        Ln.e(f);
                    }
                } finally {
                    doFinally();
                }
     
                return null;
            }
     
            protected void doPreExecute() throws Exception {
                postToUiThreadAndWait( new Callable<Object>() {
                    public Object call() throws Exception {
                        parent.onPreExecute();
                        return null;
                    }
                });
            }
     
            protected ResultT doCall() throws Exception {
                return parent.call();
            }
     
            protected void doSuccess( final ResultT r ) throws Exception {
                postToUiThreadAndWait( new Callable<Object>() {
                    public Object call() throws Exception {
                        parent.onSuccess(r);
                        return null;
                    }
                });
            }
     
            protected void doException( final Exception e ) throws Exception {
                if( parent.launchLocation!=null ) {
                    final ArrayList<StackTraceElement> stack = new ArrayList<StackTraceElement>(Arrays.asList(e.getStackTrace()));
                    stack.addAll(Arrays.asList(parent.launchLocation));
                    e.setStackTrace(stack.toArray(new StackTraceElement[stack.size()]));
                }
                postToUiThreadAndWait( new Callable<Object>() {
                    public Object call() throws Exception {
                        if( e instanceof InterruptedException || e instanceof InterruptedIOException )
                            parent.onInterrupted(e);
                        else
                            parent.onException(e);
                        return null;
                    }
                });
            }
     
            protected void doThrowable( final Throwable e ) throws Exception {
                if( parent.launchLocation!=null ) {
                    final ArrayList<StackTraceElement> stack = new ArrayList<StackTraceElement>(Arrays.asList(e.getStackTrace()));
                    stack.addAll(Arrays.asList(parent.launchLocation));
                    e.setStackTrace(stack.toArray(new StackTraceElement[stack.size()]));
                }
                postToUiThreadAndWait( new Callable<Object>() {
                    public Object call() throws Exception {
                        parent.onThrowable(e);
                        return null;
                    }
                });
            }
     
            protected void doFinally() throws Exception {
                postToUiThreadAndWait( new Callable<Object>() {
                    public Object call() throws Exception {
                        parent.onFinally();
                        return null;
                    }
                });
            }
     
     
            /**
             * Posts the specified runnable to the UI thread using a handler,
             * and waits for operation to finish.  If there's an exception,
             * it captures it and rethrows it.
             * @param c the callable to post
             * @throws Exception on error
             */
            protected void postToUiThreadAndWait( final Callable c ) throws Exception {
                final CountDownLatch latch = new CountDownLatch(1);
                final Exception[] exceptions = new Exception[1];
     
                // Execute onSuccess in the UI thread, but wait
                // for it to complete.
                // If it throws an exception, capture that exception
                // and rethrow it later.
                handler.post( new Runnable() {
                    public void run() {
                        try {
                            c.call();
                        } catch( Exception e ) {
                            exceptions[0] = e;
                        } finally {
                            latch.countDown();
                        }
                    }
                });
     
                // Wait for onSuccess to finish
                latch.await();
     
                if( exceptions[0] != null )
                    throw exceptions[0];
     
            }
     
        }
     
    }
    

    引用:http://westyi.iteye.com/blog/714935#http://blog.chinaunix.net/uid-23093301-id-190969.html

    展开全文
  • 最近因为要做一个基于深度学习的人脸识别项目,要用到TensorFlow,但是下载完成后后发现import tensorflow总是出现FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future ...
  • 17 Future

    2020-01-10 22:39:54
    文章目录在future中运行任务等待结果 并发应用 在Future{}里的代码块是并发执行的 future要么成功得到一个结果,要么以异常失败 用回调实现future完成时收到通知,串联回调比较麻烦 map/flatMap或for组合多个...
  • Java是如何实现Future模式的?万字详解!

    千次阅读 多人点赞 2020-06-26 12:12:23
    1 Future是什么? 先举个例子,我们平时网购买东西,下单后会生成一个订单号,然后商家会根据这个订单号发货,发货后又有一个快递单号,然后快递公司就会根据这个快递单号将网购东西快递给我们。在这一过程中,这一...
  • java Future

    2019-09-25 09:41:35
    Future Future 接口位于java.util.concurrent包下,是Java 1.5中引入的接口。 Future主要用来对具体的Runnable或Callable任务 进行取消任务、判断任务是否完成、获取任务执行结果。 当你提交一个Callable对象给...
  • Callable和Future

    万次阅读 2021-03-10 17:48:21
    它们俩其实挺有意思,在运行的时候各司其职,Callable产生结果,Future获取结果。 使用步骤如下: 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值; 创建 ...
  • Future、ExecutorService

    万次阅读 2020-12-22 09:36:47
    3.1 Future 我们刚才说 Callable 是可以返回子线程执行结果的,在获取结果的时候,就需要用到 Future 接口了。 Future 接口注释上写了这些: 定义了异步计算的接口,提供了计算是否完成的 check、等待完成和取回等...
  • Scala Future

    2019-10-07 08:46:02
    Future scala.concurrent.Future 异步执行代码块 import java.time._ import scala.concurrent._ import ExecutionContext.Implicits.global // 全局线程池 Future { Thread.sleep(10000) ...
  • Guava Future

    千次阅读 2019-05-21 10:49:20
    Guava Future 能够 减少主函数的等待时间,使得多任务能够异步非阻塞执行 ListenableFuture是可以监听的Future,它是对java原生Future的扩展增强。Future表示一个异步计算任务,当任务完成时可以得到计算结果。如果...
  • FutureWarning

    千次阅读 2020-05-15 13:33:04
    D:\Users\WH\anaconda3\lib\site-packages\tensorflow\python\framework\dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will...
  • 目录future简介std::future对象只有在有效的(valid)情况下才有用(useful)查询future对象是否有效future的拷贝构造函数是被禁用的对future的处理四种方式获取future的状态future_status的三种状态: future简介 ...
  • Future类型

    千次阅读 2019-10-10 17:35:20
    Future是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果的接口。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。 它的接口定义如下: public interface Future...
  • Future模式

    千次阅读 2018-08-23 22:57:42
    Future模式是多线程开发中常见的设计模式,它的核心思想是异步调用。对于Future模式来说,它无法立即返回你需要的数据,但是它会返回一个契约,将来你可以凭借这个契约去获取你需要的信息。 这是传统的同步方法,...
  • Future模式学习

    2017-02-13 23:33:35
    Future模式
  • Future的使用

    2019-06-08 21:53:15
    Future介绍
  • Dart之Future

    千次阅读 2020-07-09 16:20:57
    Future Dart类库有非常多的返回Future或者Stream对象的函数。 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作。而不是等到这个操作完成。 async和await关键词支持了异步编程,允许...
  • 深度学习Theory Future

    万次阅读 2019-12-14 13:20:32
    Theory Future Distilling the knowledge in a neural network (2015), G. Hinton et al. [pdf] Deep neural networks are easily fooled: High confidence predictions for unrecognizable images (2015), A. Nguy...
  • 三、使用Callable,Future返回结果 总结:future封装了callable,thread封装future。将callable的返回结果封装在future中,thread封装future,这样thread执行完后,就可以从future中拿取线程执行结果。 总结:...
  • future - Future 语句定义 __future__ 是一个真正的模块。 Python 提供了 __future__ 模块,把下一个新版本的特性导入到当前版本,我们就可以在当前版本中测试一些新版本的特性。 Python 为了确保你能顺利过渡到新...
  • Future CompletableFuture 使用

    千次阅读 2020-08-13 03:08:17
    1-Future简介 1.1 简介 Future 就是一个接口, 用于异步获取任务回调结果,这样中途可以做其他事,等到要取出结果再去取出, 它代表的是一种未来能获取到结果的对象 1.2-Future源码 public interface Future<V> ...
  • in future 和 in the future用法的区别

    万次阅读 2017-10-14 10:38:12
    in future 和当前的事情有关系,比如说今天迟到了,老师警告说今后要按时到学校哦,就用in future。in the future 只是一种抽象的概念,词组有in the near/distant future, 不久/很久以后。牛津例句1. Please be ...
  • Future对象

    千次阅读 2018-09-10 13:57:20
    Future对象 作用: 接收异步线程返回的结果 场景: 任务A和任务B,如果任务A需要任务B的返回结果,两种实现:  1:AB在一个线程中,A等待B返回结果,如果B的处理时间长,A不能做其他事情  2:A,B在不同线程中,A可以...
  • Netty中的Future和JDK中的Future的区别JDK1.5中Future的缺陷Netty中Future的解决办法Netty中Future的其他拓展 近期在学习Netty的时候,看到了Netty中有一个和JDK中同名的Future接口,并继承了该接口,便做一个记录...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 124,641
精华内容 49,856
关键字:

future