首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FutureTask get()方法可能是可扩展的LockSupport.park

FutureTask get()方法可能是可扩展的LockSupport.park
EN

Stack Overflow用户
提问于 2021-04-16 03:47:08
回答 1查看 139关注 0票数 0

我发现FutureTask get()方法可以在oracle jdk8中发布LockSupport.park

我的代码是:

代码语言:javascript
复制
        ExecutorService service = Executors.newFixedThreadPool(1, (r) -> {
            Thread thread = new Thread(r);
            thread.setDaemon(true);
            return thread;
        });

        Future<String> submit = service.submit(() -> {
            TimeUnit.SECONDS.sleep(5);
            System.out.println("exec future task..");
            return "a";
        });

        System.out.println(submit.get());

        LockSupport.park(new Object());
        System.out.println("error,unPark");
    }

我原以为System.out.println("error,unPark");不会执行,但它执行了

代码语言:javascript
复制
exec future task..
a
error,unPark

为了模拟线程调度,我在FutureTask代码行418上断点。

queued = UNSAFE.compareAndSwapObject(this, waitersOffset, q.next = waiters, q);

在打印exec future task..前快速超越

打印exec future task..一段时间后,继续执行..。

然后跳过LockSupport.park(new Object());并打印error,unPark

我认为

1.在服务生中添加获取线程(Main);

2.执行线程(线程池)完成任务,解除所有等待者;

3.获取线程(主)读取状态并找到任务哈希,然后返回结果并跳过执行FutureTask locksupport.park()

4.由于unpark方法是在futuretask中执行的,因此可以跳过LockSupport.park(new Object());并打印error,unPark

是虫子吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-16 08:04:11

文献资料确实说:

为线程调度目的禁用当前线程,除非许可可用。 如果许可可用,则使用它并立即返回调用;否则,出于线程调度的目的,当前线程将被禁用,并处于休眠状态,直到发生以下三种情况之一:

  • 其他一些线程调用以当前线程为目标的unpark;或
  • 其他一些线程中断当前线程;或
  • 虚假调用(即,无缘无故)返回。

此方法不报告其中哪一个导致方法返回。调用者首先应该重新检查导致线程停车的条件。调用方还可以确定,例如,返回时线程的中断状态。

光是第三颗子弹就足以告诉您,您不能假设从park返回意味着您正在等待的条件已经满足。

通常,此工具用于不能为检查/诱导条件的操作和park/unpark调用假定原子性的代码。

如文档所示,您必须在从park返回后重新检查条件。特别强调“re-”;因为这意味着您可能会发现park的返回并不是因为您的条件得到满足,所以您可能已经消耗了一个不适合您的unpark。这反过来意味着,您还必须在调用park之前测试条件,而不是在条件已经满足时调用它。但是,如果这样做,则可能在调用park时跳过unpark,因此一些后续的park调用将立即返回。

简而言之,即使没有“虚假返回”,您也必须在调用park之前测试您的特定条件,并在从park返回后在一个循环中重新检查条件,如果您想等待该条件的话。

请注意,它的大部分也适用于在一个wait块中使用synchronized /notify,或者在拥有一个Lock时使用await/signal。这两种方法都应该与预测试循环一起使用,以获得可靠的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67118821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档