future.get后线程运行一定结束吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了future.get后线程运行一定结束吗相关的知识,希望对你有一定的参考价值。

参考技术A future.get后线程运行一定结束
getAttribute获取的是初始值,而点号获取的是初始值或者.value修改后的值,例如当访问者输入了某些字符后,'value' attribute 在 property 更新后维持了原始值。原始值可以用来检验 input 是否变化,或者重置它。
对于style和onclick等事件处理程序,getAttribute方法访问时会返回字符串,而点号返回的是相应的对象和事件处理函数。
对于input中的checked属性
代码如下:

<script>
var input = document.body.children[0]
alert( input.checked ) // true
alert( input.getAttribute('checked') ) // empty string
</script>

getAttribute获取的是你是实际设置的值。而点号返回的是布尔值。
浏览器兼容性上的差别
1.在IE<9的浏览器中,可以用点号和getAttribute在相互之间访问自定义属性。
2.IE<8(包括IE8种的IE7兼容模式),property和attribute相同。因为attribute对大小写不敏感,在这种情况下,用getAttribute访问特性的时候,浏览器会选择第一次出现的值。本回答被提问者采纳

如何使用 executor.execute 和 future.get() 结束任务(使线程超时)(通过上升中断)而不阻塞主线程

【中文标题】如何使用 executor.execute 和 future.get() 结束任务(使线程超时)(通过上升中断)而不阻塞主线程【英文标题】:How to end a task(timeout a thread) (by rising interrupt) using executor.execute and future.get() without blocking the main thread 【发布时间】:2021-12-31 09:34:05 【问题描述】:

我尝试在执行器服务中使用 future,它可以在不阻塞主线程的情况下工作。然而,这最终会创建双倍数量的线程,这是不可取的。在下面的代码中,我能够在没有阻塞的情况下使用 future.get(),但我必须创建双倍的线程数

 for (int i : array) 
                executor.execute(() -> 
                    Future f = new FutureTask(() -> 
                        Goring goring = new Goring();
    
                        goring.goring(i);
    
                    , null);
                    Thread thread = new Thread((Runnable) f);
                    thread.start();
    
                    try 
                        f.get(1, TimeUnit.NANOSECONDS);
                     catch (InterruptedException | ExecutionException | TimeoutException|RuntimeException e) 
                        // TODO Auto-generated catch block
                        // System.out.println(e.getMessage());
                        e.printStackTrace();
                        f.cancel(true);
                    
    
                );
            
            
    
        executor.shutdown();
    
        

【问题讨论】:

没有任务会在一纳秒内完成,因此您可以通过根本不执行任何操作来简化所有代码。在更一般的情况下,您可以为每个 goring 调用创建一个 Callable,然后将所有 Callable 一次性提交给 ExecutorService.invokeAll,并设置超时时间。 您好,感谢您的回复,实际上这段代码是虚拟的,我必须在更大的应用程序中实现这个逻辑,如果说我的客户只想并行执行 3 个任务而不是全部 10 个任务,我必须一次分配所有任务跨度> 【参考方案1】:

通常我会推荐使用ExecutorService.invokeAll,它允许提交任意数量的超时任务,并在超时到期时取消任何尚未完成的任务。

但您已在评论中声明您希望能够以较小的并行组提交任务,例如一次并发运行的任务不超过三个。

您可以创建一个并行度有限的线程池:

ExecutorService executor = Executors.newFixedThreadPool(3);

这里的挑战是您希望在任务开始时开始超时,而不是在提交任务时开始。由于提交的任务无法访问自己的 Future,我将使用 SynchronousQueue 等待从提交线程传递的 Future:

ScheduledExecutorService cancelScheduler =
    Executors.newSingleThreadScheduledExecutor();

for (int i : array) 
    SynchronousQueue<Runnable> cancelQueue = new SynchronousQueue<>();

    Future<?> task = executor.submit(() -> 
        Runnable canceler = cancelQueue.take();
        cancelScheduler.schedule(canceler, 5, TimeUnit.SECONDS);

        Goring goring = new Goring();
        goring.goring(i);

        return null;
    );

    cancelQueue.put(() -> task.cancel(true));


executor.shutdown();
cancelScheduler.shutdown();

顾名思义,Executors.newSingleThreadScheduledExecutor() 只使用一个线程进行所有调度,这非常适合您的目的,因为调度任务只调用 Future.cancel,所花费的时间可以忽略不计。

在任务中包含return null; 的原因是从 lambda 返回值使其成为 Callable 而不是 Runnable。 (Runnable 的 run 方法的返回类型为 void,因此返回值的存在告诉编译器这个 lambda 不可能代表 Runnable。)这意味着它的签名中隐含了 throws Exception,所以没有需要捕获cancelQueue.take() 可能抛出的InterruptedException。

【讨论】:

以上是关于future.get后线程运行一定结束吗的主要内容,如果未能解决你的问题,请参考以下文章

java8 之CompletableFuture -- 如何构建异步应用

Java Future源码分析

Observable 和 Future.get 之间有啥区别吗

异常传播和 std::future

FutureTask的get()方法之异常处理

异步编程之Future和Listener