首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确同步AsynchronousSocketChannel上的并发读写

如何正确同步AsynchronousSocketChannel上的并发读写
EN

Stack Overflow用户
提问于 2012-09-14 12:17:21
回答 1查看 1.8K关注 0票数 5

我试图在vert.x工作项的AsynchronousSocketChannel上使用CompletionHandler而不是Futures实现单个请求/响应。来自vert.x文档:

“员工眩晕从来不会由多个线程同时执行。”

下面是我的代码(不确定我的套接字处理是否100%正确-请评论):

代码语言:javascript
复制
    // ommitted: asynchronousSocketChannel.open, connect ...

    eventBus.registerHandler(address, new Handler<Message<JsonObject>>() {
        @Override
        public void handle(final Message<JsonObject> event) {
            final ByteBuffer receivingBuffer = ByteBuffer.allocateDirect(2048);
            final ByteBuffer sendingBuffer = ByteBuffer.wrap("Foo".getBytes());

            asynchronousSocketChannel.write(sendingBuffer, 0L, new CompletionHandler<Integer, Long>() {
                public void completed(final Integer result, final Long attachment) {
                    if (sendingBuffer.hasRemaining()) {
                        long newFilePosition = attachment + result;
                        asynchronousSocketChannel.write(sendingBuffer, newFilePosition, this);
                    }

                    asynchronousSocketChannel.read(receivingBuffer, 0L, new CompletionHandler<Integer, Long>() {
                        CharBuffer charBuffer = null;
                        final Charset charset = Charset.defaultCharset();
                        final CharsetDecoder decoder = charset.newDecoder();

                        public void completed(final Integer result, final Long attachment) {
                            if (result > 0) {
                                long p = attachment + result;
                                asynchronousSocketChannel.read(receivingBuffer, p, this);
                            }

                            receivingBuffer.flip();

                            try {
                                charBuffer = decoder.decode(receivingBuffer);
                                event.reply(charBuffer.toString()); // pseudo code
                            } catch (CharacterCodingException e) { }


                        }

                        public void failed(final Throwable exc, final Long attachment) { }
                    });
                }

                public void failed(final Throwable exc, final Long attachment) { }
            });
        }
    });

在负载测试期间,我碰到了许多ReadPendingException和WritePendingException,如果句柄方法中一次确实只有一个线程,这似乎有点奇怪。如果一次只有一个线程在使用AsynchronousSocketChannel,那么怎么可能读或写没有完全完成呢?

EN

回答 1

Stack Overflow用户

发布于 2012-09-14 13:23:01

来自AsynchronousSocketChannel的处理程序是在他们自己的AsynchronousChannelGroup上执行的,这是ExecutorService的派生。除非您特别努力,否则处理程序将与启动I/O操作的代码并行执行。

要在竖线内执行I/O完成处理程序,您必须从该垂直线创建并注册一个处理程序,该处理程序现在执行AsynchronousSocketChannel处理程序所做的操作。

AsynchronousSocketChannel的处理程序只应将其参数(结果和附件)打包到消息中,并将该消息发送到事件总线。

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

https://stackoverflow.com/questions/12424412

复制
相关文章

相似问题

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