精华内容
参与话题
问答
  • 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,转载请注明。

    展开全文
  • Future

    2018-04-29 09:38:24
    Future的核心思想是:一个方法f,计算过程可能非常耗时,等待f返回,显然不明智。 可以在调用f的时候,立马返回一个Future,可以通过Future这个数据结构去控制方法f的计算过程。 public interface Future&lt;V&...
    Future的核心思想是:一个方法f,计算过程可能非常耗时,等待f返回,显然不明智。
     可以在调用f的时候,立马返回一个Future,可以通过Future这个数据结构去控制方法f的计算过程。
    
    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;
    }

    当我们在调用接口

    ExecutorService:  

    <T> Future<T> submit(Callable<T> task);
    
    <T> Future<T> submit(Runnable task, T result);
    
    Future<?> submit(Runnable task);
    实际上是在调用  抽象类AbstractExecutorService中的方法
    abstract class AbstractExecutorService implements ExecutorService
    器源码
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
     return new FutureTask<T>(runnable, value);

    }
    
    
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }
    
    
    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;
    }

    类 FutureTask类

    FutureTask实现了RunnableFuture接口,而RunnableFuture继承了Runnable, Future接口,因此FutureTask也是实现了Future接口的哈,即具有Future的所有特性。

        public class FutureTask<V> implements RunnableFuture<V> 
    
        public interface RunnableFuture<V> extends Runnable, Future<V> 

    构造方法:

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    
     创建一个FutureTask对象,执行的还是里面所包含的Runnable对象,如果Runnable对象正常执行完成,则此FutureTask对象调用get方法的时候就会得到结果reulst。
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }
    /**注意
    将Runnable适配为一个Callable对象, 转化为的对象虽然是Callable对象了
    但是调用此对象的call方法其实就是调用了Runnable接口的run方法并且返回值是null。
    
    public static <T> Callable<T> callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter<T>(task, result);
    }
    */

    看下RunnableAdapter类,此类实现了Callable接口。

       // Non-public classes supporting the public methods
    
        /**
         * A callable that runs given task and returns given result
         */
        static final class RunnableAdapter<T> implements Callable<T> {
            final Runnable task;
            final T result;
            RunnableAdapter(Runnable task, T result) {
                this.task = task;
                this.result = result;
            }
            public T call() {
                task.run();
                return result;
            }
        }

    FutureTask也存在生命周期。如下:

    1、NEW(开始状态)

    2、COMPLETING(正在运行状态)

    3、NORMAL (正常运行完结束状态)

    4、EXCEPTIONAL (异常状态)

    5、CANCELLED (取消状态)

    6、INTERRUPTING (中断)

    7、INTERRUPTED (中断结束状态)

    * Possible state transitions:
         * NEW -> COMPLETING -> NORMAL
         * NEW -> COMPLETING -> EXCEPTIONAL
         * NEW -> CANCELLED
         * NEW -> INTERRUPTING -> INTERRUPTED
         */
        private volatile int state;
        private static final int NEW          = 0;
        private static final int COMPLETING   = 1;
        private static final int NORMAL       = 2;
        private static final int EXCEPTIONAL  = 3;
        private static final int CANCELLED    = 4;
        private static final int INTERRUPTING = 5;
        private static final int INTERRUPTED  = 6;

    一个FutureTask新建出来,state就是NEW状态;COMPETING和INTERRUPTING用的进行时,表示瞬时状态,存在时间极短(为什么要设立这种状态???不解);NORMAL代表顺利完成;EXCEPTIONAL代表执行过程出现异常;CANCELED代表执行过程被取消;INTERRUPTED被中断

    2)执行过程顺利完成:NEW -> COMPLETING -> NORMAL

    3)执行过程出现异常:NEW -> COMPLETING -> EXCEPTIONAL

    4)执行过程被取消:NEW -> CANCELLED

    5)执行过程中,线程中断:NEW -> INTERRUPTING -> INTERRUPTED

    FutureTask类中的cancel方法如下,

    1、任务当前状态不为初始状态,则返回false

    2、任务当前装填为初始状态,但是可能刚刚中断或者是取消而CAS操作不成功,也是返回false。

    3、如果允许中断,则中断任务,返回true。

    此方法返回后任务要么处于运行结束状态,要么处于取消状态。isDone()将永远返回true,如果cancel()方法返回true,isCancelled()始终返回true。

        public boolean cancel(boolean mayInterruptIfRunning) {
            if (!(state == NEW &&
                  UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                      mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
                return false;
            try {    // in case call to interrupt throws exception
                if (mayInterruptIfRunning) {
                    try {
                        Thread t = runner;
                        if (t != null)
                            t.interrupt();
                    } finally { // final state
                        UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                    }
                }
            } finally {
                finishCompletion();
            }
            return true;
        }
    
    
            /**
         * Removes and signals all waiting threads, invokes done(), and
         * nulls out callable.
         */
        private void finishCompletion() {
            // assert state > COMPLETING;
            for (WaitNode q; (q = waiters) != null;) {//唤醒等待的所有线程节点
                if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
                    for (;;) {
                        Thread t = q.thread;
                        if (t != null) {
                            q.thread = null;
                            LockSupport.unpark(t);
                        }
                        WaitNode next = q.next;
                        if (next == null)
                            break;
                        q.next = null; // unlink to help gc
                        q = next;
                    }
                    break;
                }
            }
    
            done();
    
            callable = null;        // to reduce footprint
        }

    小结

    需要注意的是以下几点

    1、Runnable对象可以通过RunnableAdapter适配器适配到Callable对象

    2、Future对象可以通过get方法获取任务的返回值

    3、FutureTask可以简单来看是对任务Runnable/Callable的封装


    FutureTask<String> future=new FutureTask<String>(new RealData("aaa"));
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    executorService.submit(future);
    System.out.println(future.get());
    public class RealData implements  Callable<String>{
        private String param;
        public RealData(){}
     //   protected  volatile String result;
        public RealData(String param){
            this.param=param;}
    
        @Override
        public String call() throws Exception {
            StringBuffer sb=new StringBuffer();
            for (int i=0;i<10;i++){
                sb.append(param);
                try {
                    Thread.sleep(100);
                }catch (Exception e){
    
                }
            }
            return sb.toString();
        }
    }

    引用:https://www.cnblogs.com/cz123/p/7693064.html
    https://blog.csdn.net/u010412719/article/details/52137262
    

    展开全文
  • 在更新完pip的版本之后 使用pip继续安装django时报了这个错 WARNING: pip is being invoked ... This will fail in a future version of pip. Please see https://github.com/pypa/pip/issues/5599 for advice on f...

    在更新完pip的版本之后 使用pip继续安装django时报了这个错

    WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
    Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
    To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
    

    大概能猜出可能是python的安装包和pip的版本对不上?但是又不想去重装安装包 到时候又会出现一些莫名其妙的bug
    因此搜索了一下
    最后用python -m pip install Django
    命令解决问题

    参考:https://www.dreamincode.net/forums/topic/418289-pip-broken/?cf_chl_captcha_tk=e1d43d08ac9131dcd5c8e4d0144d02b8e921111d-1581578727-0-AY4v0hLRx7TpmcYaZPNiZB-evodxHYaTswGYDvdLLWVRt20axGxZsmftzv8FbH67aaCRC7i4n2JRuyBeKm0yq4sSnrLit3pTiORMX6ckULjzL4BfGuUXZDFN2DFF24-yaAOPWLtzqqsecY7URkC4cmp30icztCoW7_n_2vkeyjO7MdweaC63NS2P4osFmqEABxUdOxFp7-ZcK19G8XWKQAdDLxbD8hB9-WLqBZwWnqrOxSdC1njc6Iwd-CaGCgz_X0x12DO65NSt_gN3wD0e_zNsJyQpiNiEjgIcQd02RZb22ZjZ9I-rjrQMc8xRjUZvqsffmy3S8fIZOWd4R9eKoiAzo5NJYGo8wg8xDE7FHCRp

    展开全文
  • 出现以下问题 解决办法 python -m 会指定你当前使用的python版本 python -m pip install torchtext(包名) 安装成功!

    出现以下问题

    在这里插入图片描述

    解决办法

    python -m 会指定你当前使用的python版本
    python -m pip install torchtext(包名)

    安装成功!
    在这里插入图片描述

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

    万次阅读 多人点赞 2018-06-06 17:24:24
    在并发编程中,我们经常用到非阻塞的模型,在之前的多线程的三种实现中,不管是继承thread类还是实现runnable接口,都无法保证获取到之前的执行结果。通过实现Callback接口,并用Future可以来接收多线程的执行结果。
  • 深度学习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...
  • 【6】Callable和Future模式

    万次阅读 2019-11-26 20:28:00
    知识点2:Future常用方法 知识点3:Future模式 知识点1:Callable 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取...
  • Future模式学习

    2017-02-13 23:33:35
    Future模式
  • Callable和Future

    2020-02-07 22:49:40
    原文链接译文链接 译者:Greenster 校对:沈义扬 Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序,并在设计中引入异步处理。Thread类、Runnable接口和Java内存管理模型使得多线程编程简单直接。...
  • JAVA核心知识点--Future

    万次阅读 2017-06-02 19:06:29
    接口 Future<V>可用于获取异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get() 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 ...
  • 以下代码若在exe中是没问题的,若在dll中大部分情况是会卡住的,然而将future换成thread又没有问题了,不知道是什么情况。 class a { public: a() { //若改为 thread 没问题 ...
  • 本章主要学习Future接口。 1.Future接口概述 Future接口代表着异步计算的结果。 Future接口提供了一些方法:查看计算是否完成、等待计算完成和获取计算结果。 只有在计算完成时,才能通过get()方法获取计算...
  • java Future

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

    千次阅读 2018-08-23 22:57:42
    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...
  • Guava Future

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

    2020-09-22 11:51:16
    继续 Dart 异步系列的第三篇 Future, 关于 Future 可以说是在 Dart 异步编程中随处可见,比如一个网络请求返回的是 Future 对象,或者访问一个 SharedPreferences 返回一个 Future 对象等等。异步操作可以让你的程序...
  • c++ boost future和lazy future

    千次阅读 2016-04-01 14:58:32
    程序流中常见的情况是,中间一段代码需要长时间运行,然后蛋疼的是后面一段代码需要这段中间代码的计算结果。比如这段代码是UI,或者这段代码是图像识别或者图形渲染等计算密集型的代码。 以前笨拙的处理方式是,新...
  • Future对象

    千次阅读 2018-09-10 13:57:20
    Future对象 作用: 接收异步线程返回的结果 场景: 任务A和任务B,如果任务A需要任务B的返回结果,两种实现:  1:AB在一个线程中,A等待B返回结果,如果B的处理时间长,A不能做其他事情  2:A,B在不同线程中,A可以...
  • Future类型

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

空空如也

1 2 3 4 5 ... 20
收藏数 58,881
精华内容 23,552
关键字:

future