首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关闭AsynchronousFileChannel的常见成语是什么?

关闭AsynchronousFileChannel的常见成语是什么?
EN

Stack Overflow用户
提问于 2022-01-29 08:34:43
回答 1查看 39关注 0票数 0

我刚刚发现下面的代码不像预期的那样工作。

代码语言:javascript
复制
try (AsynchronousFileChannel channel = open(path)) {
    channel.read(, , ,
                 new CompletionHandler() {
                         @Override
                         public void completed(Integer result, Long attachment) {
                         }
                         @Override
                         public void failed(Throwable exc, Long attachment) {
                             // channel already has been closed!!!
                         }
                 });
}

因为AsynchronousFileChannel#read方法立即返回,而CompletionHandler无法工作。

在任务完成后,关闭通道的常用习语是什么?

我应该这么做吗?

代码语言:javascript
复制
AsynchronousFileChannel channel = open(path);

channel.read(, , ,
             new CompletionHandler() {
                     @Override
                     public void completed(Integer result, Long attachment) {
                     }
                     @Override
                     public void failed(Throwable exc, Long attachment) {
                     }
             });

channel.close();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-29 16:15:20

希望有人知道一个正确的方法来确保所有正在进行的AsynchronousFileChannel回调都完成了--我找不到一个合适的API调用来结束带回调的读操作。在测试中,我注意到在我的方法调用将数据读入其调用方之后,可能会调用CompletionHandler回调,这是在离开关闭AsynchronousFileChannel的try with资源块之后进行的。

代码语言:javascript
复制
try (AsynchronousFileChannel fc = AsynchronousFileChannel.open(p, StandardOpenOption.READ)) {
    var handler = new CompletionHandler<Integer,Long>() {
        public void completed(Integer result, Long position) {
            // ...
        }
        public void failed(Throwable exc, Long position) {
            // ...
        }
    };
    // Run some reads:
    fc.read(aByteBuffer, startPos, Long.valueOf(startPos), handler);
}
return blah; 
// "handler" still can receive callbacks after this point!

相反,我在方法中使用了一个使用CountDownLatch的解决方案,这样直到所有的fc.read调用都与对应的CompletionHandler completed / failed回调匹配后,才会退出try-catch块。

代码语言:javascript
复制
try (AsynchronousFileChannel fc = AsynchronousFileChannel.open(p, StandardOpenOption.READ)) {

    // Work out how many fc.read calls you plan to do
    int numberOfReads = 1;
    CountDownLatch countdown = new CountDownLatch(numberOfReads);

    var handler = new CompletionHandler<Integer,Long>() {
        public void completed(Integer result, Long position) {
            // ...
            countdown.countDown();
        }
        public void failed(Throwable exc, Long position) {
            // ...
            countdown.countDown();
        }
    };

    // Kick off numberOfReads x fc.read
    fc.read(yourByteBuffer, startPos, Long.valueOf(startPos), handler);

    // Without next line the AsynchronousFileChannel may continue to run after return
    countdown.await();
}
return blah; 
// No more "handler" callbacks after this point

这不是一个理想的解决方案,因为它依赖于在创建CountDownLatch之前计算读取数。相反,您可以考虑使用动态计数器,或者使用非回调读取方法:Future<Integer> fut = read(ByteBuffer, long)样式,并在调用线程中调用fut.get();

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

https://stackoverflow.com/questions/70903602

复制
相关文章

相似问题

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