【发布时间】:2017-03-13 14:10:46
【问题描述】:
所以我一直在检查将Closeable 接口与ExecutorService 结合使用的可能性。然后我看到 Lukas 回答 here 这只是使用方法参考:
ExecutorService service = Executors.newSingleThreadExecutor();
try (Closeable close = service::shutdown) {
}
所以我一直在挖掘并想在尝试块中初始化服务:
@Test(expected = RejectedExecutionException.class)
public void singleThreadTest() throws Exception {
ExecutorService es = null;
try (Closeable closeable = (es = Executors.newSingleThreadExecutor())::shutdown){
es.execute(()->System.out.println("executed " + Thread.currentThread().getId()));
}
System.out.println("executed " + Thread.currentThread().getId());
System.out.println(es.isShutdown());
es.execute(()->{});
}
这部分相当不错,eclipse有点困惑,但如果有异常我相信它会被压制,那么我已经尝试过:
@Test(expected = RejectedExecutionException.class)
public void singleThreadTest() throws Exception {
ExecutorService es = null;
try (Closeable closeable = es::shutdown){
es = Executors.newSingleThreadExecutor();
es.execute(()->System.out.println("executed " + Thread.currentThread().getId()));
}
System.out.println("executed " + Thread.currentThread().getId());
System.out.println(es.isShutdown());
es.execute(()->{});
}
对于这个代码块,我得到NullPointerException,但代码块成功执行(创建了新线程,但在 close() 阶段我得到了异常)。我注意到,当我声明时:
Closeable closeable = es::shutdown
es 必须是(有效地)最终的,这个问题只发生在双冒号运算符上。即下面一个不编译:
try (Closeable closeable = new Closeable() {
@Override
public void close() throws IOException {
es.shutdown();
}
}){
这是一个错误吗?这是什么原因? *方法参考impl? *IDE *JVM (oracle - debian)?
跟进:
@Test(expected = RejectedExecutionException.class)
public void singleThreadTest() throws Exception {
ExecutorService es = null;
es = Executors.newSingleThreadExecutor();
es = Executors.newSingleThreadExecutor();
es = null;
try (Closeable closeable = ()->es.shutdown();){
es = Executors.newSingleThreadExecutor();
es.execute(()->System.out.println("executed " + Thread.currentThread().getId()));
}
System.out.println("executed " + Thread.currentThread().getId());
System.out.println(es.isShutdown());
es.execute(()->{});
}
此代码无法编译,但可以:
@Test(expected = RejectedExecutionException.class)
public void singleThreadTest() throws Exception {
ExecutorService es = null;
es = Executors.newSingleThreadExecutor();
es = Executors.newSingleThreadExecutor();
es = null;
try (Closeable closeable = es::shutdown;){
es = Executors.newSingleThreadExecutor();
es.execute(()->System.out.println("executed " + Thread.currentThread().getId()));
}
System.out.println("executed " + Thread.currentThread().getId());
System.out.println(es.isShutdown());
es.execute(()->{});
}
【问题讨论】:
-
我觉得你的文字有点混乱。例如,缺少分隔不同句子的标点符号?而且您的源代码在某些部分的格式也很奇怪。不是很容易阅读输入。并且为了记录:至少据我所知,它被称为 方法引用 不是双冒号运算符。
-
那么这两个问题中的哪一个是重复的? stackoverflow.com/q/33052917/476716stackoverflow.com/q/4732544/476716
-
Objects.requireNonNull用于显示等价性。规范要求捕获的引用在被捕获时立即测试null,就像使用es::shutDown,而不是将其推迟到调用Closeable.close()的时刻。无论哪种情况,它都会在运行时失败。 -
不,不,这不是编译时检查(尽管您的 IDE 可能会警告您)。我所说的是,当 进入
try块并执行Closeable closeable = es::shutdown时它将失败,而不是等待离开try块并尝试调用close()的那一刻,这将调用shutdown。这与ExecutorService es = null; try(Closeable closeable = () -> es.shutdown())不同,后者将在退出时失败。