分享
 
 
 

nio 的使用方法

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

使用nio最尴尬的莫过于一不小心cpu利用率就维持在100%,一般的原因可能是

注册了OP_WRITE事件

对某个注册事件一直没处理(或没处理完)使用nio应该注意:

只在一个线程中操作selector(在多个线程中操作同一个selector就是一场噩梦)

只注册当前感兴趣的事件

要发送数据时直接写,一次写不完再注册OP_WRITE事件,在下一次可写时发送

实践代码:

SelectorProcessor类,分发事件(最好使用线程池)

package zzzhc;

import java.io.IOException;

import java.nio.channels.ClosedChannelException;

import java.nio.channels.ClosedSelectorException;

import java.nio.channels.SelectableChannel;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.util.Iterator;

/**

* @author <a href="zzzhc'mailto:zzzhc0508@hotmail.com">zzzhc </a>

*

*/

public class SelectorProcessor implements Runnable {

private final Selector selector;

private final Queue waitCloseQueue;

private final Queue waitRegisterQueue;

private final Queue waitAddInterestQueue;

private final Thread processorThread;

private boolean shutdown = false;

private final static SelectorProcessor instance;

static {

try {

instance = new SelectorProcessor();

} catch (IOException e) {

throw new RuntimeException(e);

}

}

public static SelectorProcessor getDefaultInstance() {

return instance;

}

public SelectorProcessor() throws IOException {

selector = Selector.open();

waitCloseQueue = new Queue();

waitRegisterQueue = new Queue();

waitAddInterestQueue = new Queue();

processorThread = new Thread(this);

//processorThread.setDaemon(true);//is this needed?

processorThread.start();

}

public void register(SelectableChannel sc, Handler handler, int ops) {

if (Thread.currentThread() == processorThread) {

doRegister(sc, handler, ops);

} else {

ChannelAssociater r = new ChannelAssociater(sc, handler, ops);

synchronized (waitRegisterQueue) {

waitRegisterQueue.push(r);

selector.wakeup();

}

}

}

public void addInterestOps(SelectableChannel sc, int addOps) {

if (Thread.currentThread() == processorThread) {

addOps(sc, addOps);

} else {

ChannelAssociater r = new ChannelAssociater(sc, null, addOps);

synchronized (waitAddInterestQueue) {

waitAddInterestQueue.push(r);

selector.wakeup();

}

}

}

public void closeChannel(SelectableChannel sc) {

if (Thread.currentThread() == processorThread) {

doClose(sc);

} else {

synchronized (waitCloseQueue) {

waitCloseQueue.push(sc);

selector.wakeup();

}

}

}

protected void doRegister(SelectableChannel sc, Handler handler, int ops) {

if (Thread.currentThread() == processorThread) {

try {

sc.register(selector, ops, handler);

} catch (ClosedChannelException e) {

e.printStackTrace();

}

}

}

protected void addOps(SelectableChannel sc, int addOps) {

if (Thread.currentThread() == processorThread) {

SelectionKey key = sc.keyFor(selector);

key.interestOps(key.interestOps() | addOps);

}

}

protected void doClose(SelectableChannel sc) {

if (Thread.currentThread() == processorThread) {

try {

sc.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

protected void dealRegister() {

if (Thread.currentThread() == processorThread) {

synchronized (waitRegisterQueue) {

while (!waitRegisterQueue.isEmpty()) {

ChannelAssociater ca = (ChannelAssociater) waitRegisterQueue

.shift();

doRegister(ca.sc, ca.handler, ca.ops);

}

}

}

}

protected void dealAddInterest() {

if (Thread.currentThread() == processorThread) {

synchronized (waitAddInterestQueue) {

while (!waitAddInterestQueue.isEmpty()) {

ChannelAssociater ca = (ChannelAssociater) waitAddInterestQueue

.shift();

addOps(ca.sc, ca.ops);

}

}

}

}

protected void dealClose() {

if (Thread.currentThread() == processorThread) {

synchronized (waitCloseQueue) {

while (!waitCloseQueue.isEmpty()) {

SelectableChannel sc = (SelectableChannel) waitCloseQueue

.shift();

doClose(sc);

}

}

}

}

protected void dealShutdown() {

Iterator iterator = selector.keys().iterator();

while (iterator.hasNext()) {

try {

SelectionKey key = (SelectionKey) iterator.next();

key.channel().close();

} catch (IOException e) {

e.printStackTrace();

}

}

try {

selector.close();

} catch (IOException e) {

e.printStackTrace();

}

}

public void shutdown() {

this.shutdown = true;

selector.wakeup();

}

public void run() {

int keyCount = 0;

while (!shutdown) {

dealRegister();

dealAddInterest();

dealClose();

try {

keyCount = selector.select();

if (keyCount == 0) {

continue;

}

Iterator iterator = selector.selectedKeys().iterator();

while (iterator.hasNext()) {

SelectionKey key = (SelectionKey) iterator.next();

iterator.remove();

key.interestOps(key.interestOps() & ~key.readyOps());

Handler handler = (Handler) key.attachment();

if (key.isAcceptable()) {

((AcceptHandler) handler).handleAccept();

} else if (key.isConnectable()) {

((ConnectHandler) handler).handleConnect();

} else {

ReadWriteHandler rwh = ((ReadWriteHandler) handler);

if (key.isValid() && key.isReadable()) {

rwh.handleRead();

} else if (key.isValid() && key.isWritable()) {

rwh.handleWrite();

}

}

}

} catch (ClosedSelectorException cse) {

System.err.println("selector closed:" + cse.getMessage()

+ "\nquit");

return;

} catch (IOException e) {

e.printStackTrace();

}

}

dealShutdown();

}

class ChannelAssociater {

SelectableChannel sc;

Handler handler;

int ops;

ChannelAssociater(SelectableChannel sc, Handler handler, int ops) {

this.sc = sc;

this.handler = handler;

this.ops = ops;

}

}

}

//Queue类,对LinkedArrayList的简单包装,提供push,pop,shift,unshift操作,用起来顺手

package zzzhc;

import java.util.*;

/**

* @author <a href="zzzhcmailto:zzzhc0508@hotmail.com">zzzhc</a>

*

*/

public class Queue {

private LinkedList content = new LinkedList();

public void unshift(Object o) {

content.addFirst(o);

}

public Object shift() {

return content.removeFirst();

}

public void push(Object o) {

content.addLast(o);

}

public Object pop() {

return content.removeLast();

}

public boolean isEmpty() {

return content.isEmpty();

}

public int size() {

return content.size();

}

}

//Handler,ConnectHandler ,AcceptHandler ,ReadWriteHandler 接口,处理事件

package zzzhc;

/**

* @author <a href="zzzhcmailto:zzzhc0508@hotmail.com">zzzhc</a>

*

*/

public interface Handler {

}

package zzzhc;

/**

* @author <a href="zzzhcmailto:zzzhc0508@hotmail.com">zzzhc</a>

*

*/

public interface ConnectHandler extends Handler {

void handleConnect();

}

package zzzhc;

/**

* @author <a href="zzzhcmailto:zzzhc0508@hotmail.com">zzzhc</a>

*

*/

public interface AcceptHandler extends Handler {

void handleAccept();

}

package zzzhc;

/**

* @author <a href="zzzhcmailto:zzzhc0508@hotmail.com">zzzhc</a>

*

*/

public interface ReadWriteHandler extends Handler {

void handleRead();

void handleWrite();

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有