精华内容
下载资源
问答
  • future.get
    2021-03-16 12:44:10

    任何人都可以指出一些文档,这些文档清楚地表明,超时为0的“Future.get”不会等待?

    java.util.concurrent.Future的API文档并没有明确表示future.get(0,unit)的行为.独立声明,“等待最多在给定时间等待…”意味着这种调用根本不会等待,但由于Object.wait(0)(无限等待)的长期行为,我要紧紧依靠未来的“不等待”行为(0,单位)

    扫描一些JDK提供的类的源(即FutureTask)我看到,当超时为0时,Future的这个特定实现不会等待.

    我想说可以

    long timeout = Math.max(until - now, 0);

    return future.get(timeout, TimeUnit.MILLISECONDS);

    但是我对未来实施这个无限等待的紧张感到紧张,所以我明确地将它编码为我期望它的工作方式:

    long timeout = Math.max(until - now, 0);

    if(timeout > 0 || future.isDone()){

    return future.get(timeout, TimeUnit.MILLISECONDS);

    } else {

    throw TimeoutException();

    }

    更多相关内容
  • 1、Future Future模式是多线程设计常用的一种设计...向线程池中提交任务的submit方法不是阻塞方法,而Future.get方法是一个阻塞方法,当submit提交多个任务时,只有所有任务都完成后,才能使用get按照任务的提交顺序得

    1、Future

    Future模式是多线程设计常用的一种设计模式。Future模式可以理解成:我有一个任务,提交给了Future,Future替我完成这个任务。期间我自己可以去做任何想做的事情。一段时间之后,我就便可以从Future那儿取出结果。
    Future提供了三种功能:
    判断任务是否完成
    能够中断任务
    能够获取任务执行的结果
    向线程池中提交任务的submit方法不是阻塞方法,而Future.get方法是一个阻塞方法,当submit提交多个任务时,只有所有任务都完成后,才能使用get按照任务的提交顺序得到返回结果,所以一般需要使用future.isDone先判断任务是否全部执行完成,完成后再使用future.get得到结果。(也可以用get (long timeout, TimeUnit unit)方法可以设置超时时间,防止无限时间的等待)
    三段式的编程:1.启动多线程任务2.处理其他事3.收集多线程任务结果,Future虽然可以实现获取异步执行结果的需求,但是它没有提供通知的机制,要么使用阻塞,在future.get()的地方等待future返回的结果,这时又变成同步操作;要么使用isDone()轮询地判断Future是否完成,这样会耗费CPU的资源。
    解决方法:CompletionService和CompletableFuture(按照任务完成的先后顺序获取任务的结果)

    2、CompletionService是java1.8之前最好用的方法,

    能够实现按照任务完成的先后顺序获取任务的结果。

    public class TestCompletionService {
    	private static final String commandstr01 = "hahah";
    	private static final String commandstr02 = "hahah";
    	
    	
    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		//1、创建一个线程池
    		ExecutorService executorService = Executors.newCachedThreadPool();
    		
    		CompletionService<String> completionService = new ExecutorCompletionService<String>(executorService);
    		
    		completionService.submit(new MyThreadt33(commandstr01));
    		completionService.submit(new MyThreadt44(commandstr01));
    			
    		executorService.shutdown();
    		
    		System.out.println(completionService.take().get());
    		System.out.println(completionService.take().get());
    	}
    }
     
    class MyThreadt33 implements Callable<String>{
    	private String commandstr;          // 要运行的mingling
    	public MyThreadt33(String commandstr) {
    		this.commandstr = commandstr;
    	}
    	@Override
    	public String call() throws Exception {
    		int sum = 0;
    		for (int i = 0; i < 100; i++) {
    			Thread.sleep(200);
    			sum += i;
    			System.out.println("Mythread3: "+i);
    		}
    		return String.valueOf(sum+300000);
    	}
    }
     
    class MyThreadt44 implements Callable<String>{
    	private String commandstr;          // 要运行的mingling
    	public MyThreadt44(String commandstr) {
    		this.commandstr = commandstr;
    	}
    	@Override
    	public String call() throws Exception {
    		int sum = 0;
    		for (int i = 0; i < 50; i++) {
    			Thread.sleep(200);
    			sum += i;
    			System.out.println("Mythread4: "+i);
    		}
    		return String.valueOf(sum+400000);
    	}
    }
    

    CompletionService方法可以通过completionService.take().get()方法获取最快完成的线程的返回结果(若当前没有线程执行完成则阻塞直到最快的线程执行结束),第二次调用则返回第二快完成的线程的返回结果。

    3、CompletableFuture接口

    所谓异步调用其实就是实现一个可无需等待被调函数的返回值而让操作继续运行的方法。简单的讲就是另启一个线程来完成调用中的部分计算,使调用继续运行或返回,而不需要等待计算结果。但调用者仍需要取线程的计算结果。

    JDK1.5新增了Future接口,用于描述一个异步计算的结果。虽然 Future 以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。

    JDK1.8后提出了CompletableFuture接口实现了Future和CompletionStage两个接口,CompletionStage可以看做是一个异步任务执行过程的抽象(CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段,一个阶段的计算执行可以是一个Function,Consumer或者Runnable。比如:

    stage.thenApply(x -> square(x)).thenAccept(x -> System.out.print(x)).thenRun(() -> System.out.println()))
    我们可以基于CompletableFuture创建任务和链式处理多个任务,并实现按照任务完成的先后顺序获取任务的结果。

    (1)创建任务

    ##使用runAsync方法新建一个线程来运行Runnable对象(无返回值);

    ##使用supplyAysnc方法新建线程来运行Supplier对象(有返回值);

    ##基于线程池创建

    (2)任务的异步处理

    不论Future.get()方法还是CompletableFuture.get()方法都是阻塞的,为了获取任务的结果同时不阻塞当前线程的执行,我们可以使用CompletionStage提供的方法结合callback来实现任务的异步处理。

    ##whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。
    ##whenCompleteAsync:把 whenCompleteAsync 这个任务继续提交给线程池来进行执行,也就是并行执行。

    ##thenApply:当一个线程依赖另一个线程时,可以使用 thenApply 方法来把这两个线程串行化

    ##thenAccept:thenAccept接收上一阶段的输出作为本阶段的输入,并消费处理,无返回结果。

    ##thenRun:不关心前一阶段的计算结果,因为它不需要输入参数,进行消费处理,无返回结果。

    ##thenCombine:会把两个 CompletionStage 的任务都执行完成后,把两个任务的结果一块交给 thenCombine 来处理。

    ##applyToEither :两个CompletionStage,谁执行返回的结果快,我就用那个CompletionStage的结果进行下一步的转化操作。

    ##acceptEither 方法:两个CompletionStage,谁执行返回的结果快,我就用那个CompletionStage的结果进行下一步的消耗操作

    public class TestCompletableFuture {
    	private static final String commandstr01 = "hahah";
    	private static final String commandstr02 = "hahah";
    	private static final String commandstr03 = "hahah";
    	private static final String commandstr04 = "hahah";
     
    	    public static void main(String[] args) throws InterruptedException, ExecutionException{
    	        
    	    	ExecutorService executorService = Executors.newCachedThreadPool();
    	    	
    	        CompletableFuture.supplyAsync(new MyThreadt444(commandstr02),executorService).whenComplete((result, e) -> {
    	        	//执行线程执行完以后的操作。
    	            System.out.println(result + " " + e);
    	        }).exceptionally((e) -> {
    	            //抛出异常
    	        	System.out.println("exception " + e);
    	            return "exception";
    	        });
    	        
    	         CompletableFuture.supplyAsync(new MyThreadt333(commandstr02),executorService).whenComplete((result, e) -> {
    	        	//执行线程执行完以后的操作。
    	        	System.out.println(result + " " + e);
    	        }).exceptionally((e) -> {
    	            System.out.println("exception " + e);
    	            return "exception";
    	        });
    	    }
    }
     
     
     
    class MyThreadt333 implements Supplier<String>{
     
    	private String commandstr;          // 要运行的mingling
    	public MyThreadt333(String commandstr) {
    		this.commandstr = commandstr;
    	}
    	@Override
    	public String get() {
    		int sum = 0;
    		for (int i = 0; i < 30; i++) {
    			try {
    				Thread.sleep(200);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			sum += i;
    			System.out.println("Mythread333: "+i);
    		}
    		return String.valueOf(sum+300000);
    	}
    }
     
    class MyThreadt444 implements Supplier<String>{
     
    	private String commandstr;          // 要运行的mingling
    	public MyThreadt444(String commandstr) {
    		this.commandstr = commandstr;
    	}
    	@Override
    	public String get() {
    		int sum = 0;
    		for (int i = 0; i < 40; i++) {
    			try {
    				Thread.sleep(200);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			sum += i;
    			System.out.println("Mythread444: "+i);
    		}
    		return String.valueOf(sum+400000);
    	}
    }
    

    在CompletableFuture接口中除了使用whenComplete还可以使用handle等方法能实现按照任务完成的先后顺序获取任务的结果。

    4、几种多线程并发取结果方式的总结
    在这里插入图片描述

    展开全文
  • callable多线程future.get()方法

    千次阅读 2021-07-19 15:35:44
    callable多线程future.get()方法能获取到当前线程的执行结果,但是会阻塞当前线程,即当前线程执行结束获取到结果后才会继续执行下一个线程,解决方法: 创建一个List数组存储funture,在所有线程执行以后遍历list...

    callable多线程future.get()方法能获取到当前线程的执行结果,但是会阻塞当前线程,即当前线程执行结束获取到结果后才会继续执行下一个线程,解决方法:
    创建一个List数组存储funture,在所有线程执行以后遍历list获取结果。

    int count = 0;
    List<Future<Integer>> res = new ArrayList<>();
    ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < list.size(); i++) {
            Callable<Integer> fun = new fun(list.get(i));
            Future<Integer> future = executorService.submit(fun);
            res.add(future);
            }
        for (Future<Integer> future : res) {
                count += future.get();
            }
    
    展开全文
  • Future.get(timeout)在给定超时后不能可靠地抛出TimeoutException。这是正常的行为还是可以做些什么来使这个更可靠?此测试在我的机器上失败。但是,如果我睡觉3000而不是2000,它会通过。public class ...

    Future.get(timeout)在给定超时后不能可靠地抛出TimeoutException。这是正常的行为还是可以做些什么来使这个更可靠?此测试在我的机器上失败。但是,如果我睡觉3000而不是2000,它会通过。

    public class FutureTimeoutTest {

    @Test

    public void test() throws

    ExecutionException,

    InterruptedException {

    ExecutorService exec = Executors.newSingleThreadExecutor();

    final Callable call = new Callable() {

    @Override

    public Object call() throws Exception {

    try {

    Thread.sleep(2000);

    } catch (InterruptedException ex) {

    ex.printStackTrace();

    }

    return 0;

    }

    };

    final Future future = exec.submit(call);

    try {

    future.get(1000, TimeUnit.MILLISECONDS);

    fail("expected TimeoutException");

    } catch (TimeoutException ignore) {

    }

    }

    }

    展开全文
  • 如果线程池的拒绝策略设置成DiscardPolicy或者DiscardOldestPolicy,通过Future获取执行结果,可能导致线程会一直阻塞。问题复现// 创建一个单线程,拒绝策略时 DiscardPolicyprivate final static ...
  • 先说说Future。 他是一个interface 也可以理解为一种设计模式。 大致如下:我有一个任务,提交给了FutureFuture替我完成这个任务。...Future里面有个方法 get 是个阻塞方法。当线程池一次性submit多个任务的时候。
  • Future f = exec.submit(() -> x()); f.get(); System.out.println("f.get() returned"); exec.shutdownNow(); System.out.println("Good bye!"); } private static Integer x() { throw new RuntimeException("An ...
  • 我的代码段:ExecutorService executor = Executors.newSingleThreadExecutor();try {Task t = new Task(response,inputToPass,pTypes,unit.getInstance(),methodName,unit....Future fut = executor.submit(t)...
  • Future向您提供get()的方法,该方法没有阻塞,如果计算完成,则返回true,否则返回false。Future用于检索计算结果。您有两种选择:请致电Future,如果结果准备就绪,可以通过调用get()要求它,请注意没有阻塞使用...
  • 有一个接口的部分功能使用了线程池,这个功能放在线程池里和主线程并行执行,等线程池里的任务执行完通过future.get的方式(如果需要得到线程池里的线程执行结果,使用future的方式)获取线程池里的线程执行结果,然后...
  • public class MyTest { public static void main(String[] args) throws Exception { ExecutorService pool = ... Future<Integer> f1 = pool.submit(new MyCallable(100)); Future<Integer> f2
  • ExecutionException和InterruptedException是两个非常不同的事情。 ExecutionException封装了正在执行的线程抛出的任何异常,所以如果线程是做某种IO导致抛出IOException异常的,那么它会被包装在一个...
  • 深入学习java源码之Callable.call()与Future.get() Callable和Future出现的原因 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。  这2种方式都有一个缺陷就是:在执行完任务之后无法...
  • static ExecutorService ... * get 出现TimeoutException,并不会中断或者取消运算线程 * @throws InterruptedException */ @Test void testGetTimeoutException() throws InterruptedException { f.
  • 大概是: 有个线程池满了,然后新的任务使用CompletableFuture.supplyAsync执行,用future1.get(1, TimeUnit.SECONDS)) 去获取的时候报错java.util.concurrent.TimeoutException 报错java.util.concurrent....
  • java超时关闭线程,用future.get() 实现

    万次阅读 2019-04-18 19:20:46
    这个我研究了两天,好多都是用的future.get(超时时间,单位)来实现,只是不同方式而已。下边来看下: 第一种: //先新建一个 ExecutorService ExecutorService exec = Executors.newSingleThreadExecutor(); //...
  • 1、Future Future模式是多线程设计常用的一种设计...向线程池中提交任务的submit方法不是阻塞方法,而Future.get方法是一个阻塞方法,当submit提交多个任务时,只有所有任务都完成后,才能使用get按照任务的提交顺序
  • public class MyTest { public static void main(String[] args) throws Exception { ExecutorService pool = ... Future<Integer> f1 = pool.submit(new MyCallable(100)); Future<Integer> f2 = .
  • 为了保证系统响应迅速,需要寻找一种方法能够使调取接口能够异步执行,而Java正好提供了类似的方法,在java.util.concurrent中包含了Future相关的类,运用其中的一些类可以进行异步计算,以减少主线程的等待时间。...
  • System.out.println(future.get()); } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { executorService.shutdown();...
  • 1. Future.get(timeout) In Java project we sometime want to run our code during a limit time , we will consider about using Future.get(time, TimeUnit), While this will not always useful , look at the
  • 设定时间的任务如果某一个子线程任务不能在...Future.get方法有一个重载,传入限制的时间V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;如果阻塞时长超过指
  • try { try { Future result = ex.submit( new Reader()); input = result.get(5, TimeUnit.SECONDS); } catch (ExecutionException e) { e.getCause().printStackTrace(); } catch (TimeoutException e){} } ...
  • std::future为一次性事件 多次使用发生崩溃
  • Java使用Future设置方法超时

    千次阅读 2021-03-16 12:43:42
    1、使用线程包java.util.concurrent.Future2、Future代表一个异步计算的结果。它提供了方法来检查是否计算已经完成,还是正在计算而处于等待状态,并且也提供了获取计算结果 方法。当计算完成后,只能通过get方法来...
  • { Log.d(TAG, "InterruptedException: " + Log.getStackTraceString(e)) } Log.d(TAG, "call end") "call success" }) try { Log.d(TAG, "futureResult : " + futureResult.get(5 * 1000, TimeUnit.MILLISECONDS)) }...
  • 记录问题,暂时还没得到解决 最近在工作中遇到这个问题,自己找了很多资料,始终没得到解决,所以发出来看看是否有人跟我遇到同样的问题,一起讨论 关于这个Future接口有以下几个方法 ... V get() throws InterruptedE
  • FutureTask.get(timeOut)执行原理浅析

    千次阅读 2020-08-23 17:54:48
    使用java多线程解决问题的时候,为了提高效率,我们常常会异步处理一些计算任务并在最后异步的获取计算结果,这个过程的实现离不开Future接口及其实现类FutureTask。FutureTask类实现了Runnable, Future接口,接下来...
  • 关于 Future get方法的疑问

    千次阅读 2021-02-12 19:37:03
    最近在看 effective java 里面有一个关于死锁的例子其中有一处代码是调用 ExecutorService.submit() 方法返回后的 Future 对象的 get 方法现在问题是如果不调用 get 方法就不会有死锁问题。刚开始还理解为并不是死锁...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 205,431
精华内容 82,172
关键字:

future.get