关于java nio新手请教几个问题

OneThin 发布于 2013/07/24 22:53
阅读 455
收藏 0

最近在看java nio相关的内容,有几个问题想请教一下,谢谢大家:

1、关于SelectionKey.OP_WRITE的用法,我的理解是当accept后取得一个SocketChannel,那服务器不是随时可以调用SocketChannel 的write方法进行写入吗,在什么情况下需要响应它的OP_WRITE再去写呢?

2、一般服务端模型都是accept,read,某些操作,write操作,假设采用nio配合多线程的模式,一般是主线程(accept的那个线程)accept后然后响应到一个通道的OP_READ后,把这个可以读的SocketChannel扔给其他线程,其他线程进行read。。。巴拉巴拉巴拉还是响应到一个通道的OP_READ的后,把数据读出来,把数据扔给其他线程处理呢?关键点就是read这个操作让哪个线程做比较合适?

加载中
0
nubo
nubo
去看netty和mina的设计就知道该怎么用, 这只是java nio的一部分。nio还提升了java处理文件的能力。
nubo
nubo
回复 @兮风古道 : 官网,还有网上很多源码解析教程
兮风古道
兮风古道
在哪看他们的设计,说说
0
m
mononite

1. 当socket的write buffer满的时候,是不能写的,当然write buffer多数情况下都不会满,所以对OP_WRITE事件要小心,一般处理方法是真需要写数据的时候才注册OP_WRITE,写完再移除。

2. 自己写nio服务器的话,能用单线程就尽量单线程;用多线程模型的话,哪个线程读都可以,只是如果在新线程中读的话,处理同步会困难一些(举个例子,怎么保证不会出现两个线程同时读一个socket),而且陷阱也多,所以一般都是selector监听线程来读socket。

0
明月照大江
明月照大江

1.write事件,是这样的,当底层缓冲区有空闲时(即能够发送数据),就会产生write事件,所以write事件是,有数据写的时候才去注册,发送结束之后就取消这个事件。但是因为很多时候处理是另外的线程,所以用别的来注册也是个问题,所以通常每一个channel对象有自己对应的发送队列,当队列不为空时注册写事件,由selector线程来将数据写入channel,队列的数据写完后取消写事件,事件的注册和取消上要加锁。如果不使用selector线程去写的话,使用别的线程就需要一个while循环去不断写直到写入缓冲,但是效果不好。

2.selector线程去将数据从channel写入buffer,然后再交出让别的线程处理,有的时候decode操作也在里面,以保证我们能将完整的数据交给处理的线程,在非阻塞中read操作的开销相当小。

java NIO 理解起来不难,最关键是为了提高处理速度,我们会在NIO模型后采用大量的线程模型,特别是网络IO部分,数据在多个线程中的转移就避免不了大量的锁操作。这个只能慢慢来了

0
TracyZhang
TracyZhang
建议楼主找些开源的看看
返回顶部
顶部