vac*_*ach 4 java concurrency java-8 try-with-resources
假设我们使用CompletableFuture.runAsync(..)运行执行,并且在runnable中我们有try-with-resources块(我们正在使用一些应该在发生任何事情时关闭的资源),并且在某些时候在try块我们没有完成执行时取消可完成的未来...尽管执行停止,应关闭的资源未关闭,AutoClosable的close()未被调用...
这是一个java问题还是有办法正确地做到这一点?没有hacky变通办法,如使用期货(支持中断等),如果它的预期行为如何处理类似的情况,当不可中断的CompletableFuture被取消...?
public class AutoClosableResourceTest {
public static class SomeService{
public void connect(){
System.out.println("connect");
}
public Integer disconnect(){
System.out.println("disconnect");
return null;
}
}
public static class AutoClosableResource<T> implements AutoCloseable {
private final T resource;
private final Runnable closeFunction;
private AutoClosableResource(T resource, Runnable closeFunction){
this.resource = resource;
this.closeFunction = closeFunction;
}
public T get(){
return resource;
}
@Override
public void close() throws Exception {
closeFunction.run();
}
}
@Test
public void testTryWithResource() throws InterruptedException {
SomeService service = new SomeService();
CompletableFuture<Void> async = CompletableFuture.runAsync(() -> {
try (AutoClosableResource<SomeService> resource = new AutoClosableResource<>(service, service::disconnect)) {
resource.get().connect();
while (true) {
Thread.sleep(1000);
System.out.println("working...");
}
} catch (Exception e) {
e.printStackTrace();
}
});
Thread.sleep(2500);
async.cancel(true);
Thread.sleep(2500);
}
}
Run Code Online (Sandbox Code Playgroud)
这将产生
connect
working...
working...
working...
working...
Run Code Online (Sandbox Code Playgroud)
你可以看到它没有调用cancel()并打开资源...
你似乎很难理解其目的CompletableFuture是什么.看看它的类文档的第一句话:
一个
Future可以明确完成(设置它的价值和地位),...
因此,与FutureTask执行其run方法的线程完成的不同,a CompletableFuture可以由任何线程完成,该线程将在任意时间点设置其值/状态.在CompletableFuture不知道哪个线程将完成它,它甚至不知道是否有目前正在其完成一个线程.
因此,CompletableFuture取消时不能中断正确的线程.这是其设计的基本部分.
如果你想要一个你可以打断的工作线程,最好使用FutureTask/ ThreadPoolExecutor.以这种方式安排的任务可能仍然CompletableFuture在其结束时完成.
| 归档时间: |
|
| 查看次数: |
2909 次 |
| 最近记录: |