【发布时间】:2021-07-11 02:26:35
【问题描述】:
我发现 FutureTask get() 方法可能会在 oracle jdk8 中禁用 LockSupport.park
我的代码是:
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");不会执行;但它确实执行了
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.FutureTask在waiters中添加获取线程(main);
2.执行线程(线程池)完成任务,解除所有等待者;
3.getting thread(main) read state,发现task hash完成,然后返回结果跳过执行FutureTask locksupport.park()
4.因为在futuretask中执行了unpark方法,所以可以跳过LockSupport.park(new Object());并打印error,unPark
这是一个错误吗?
【问题讨论】:
-
“distable”似乎不是一个词。进一步注意,不需要像
LockSupport.park(new Object());那样指定无意义的对象。如果无法提供有意义的对象进行监控,就使用LockSupport.park();。
标签: java java-8 concurrency java.util.concurrent futuretask