您的位置:首页 > 其它

NIO[读]、[写]在同一线程(单线程)中执行,让CPU使用率最大化,提高处理效率

2015-06-17 14:37 302 查看
前几天写过一篇文章,讨论重写服务后,用ab进行压力测试,发现使用NIO后没提高什么性能,只是CPU使用率提高了,内存占用降低了。

之前的NIO实现模式,主要参考(基于事件的NIO多线程服务器)http://www.ibm.com/developerworks/cn/java/l-niosvr/

实现方式:把[读],[写]放在不同的线程中运行,主线程(Selector)中我使用了ConcurrentLinkedQueue队列,

//准备写

public static void readyWrite(SelectionKey key)
{
writeQueue.add(key);

selector.wakeup(); //激活selector.select();
}


//准备读

public static void readyRead(SelectionKey key)
{
readQueue.add(key);

selector.wakeup();
}


由于[读]、[写]是在各自的线程中运行,只要有读或写的时候,都要执行selector.wakeup();
我今天无意看到网上有人说,selector.wakeup();调用太多,影响性能。

我就试着把[读]、[写]重新放在一个线程中运行,然后再用ab压力测试,发现当开启持久连接后,性能上升了30%。

真没想到,会是这样的结果,不过由于服务中有的时候需要返回一些动态内容(有可能是一些耗时的业务),对于这部分情况肯定不能放在单线程中执行,不然,NIO会卡住,无法响应新用户的请求,我把这一部分动态页面放在一个线程池中执行:

//准备写
public static void readyWrite(SelectionKey key)
{
key.interestOps(SelectionKey.OP_WRITE);
}

//在多线程中(Page子类),准备写,需要同时激活selector.wakeup();
public static void readyWriteAndWakeup(SelectionKey key)
{
//测试发现,极少数情况下key 有可能=null,比如执行了Request.close()后
if (key != null)
{
key.interestOps(SelectionKey.OP_WRITE);
selector.wakeup();
}
}

//准备读
public static void readyRead(SelectionKey key)
{
key.interestOps(SelectionKey.OP_READ);
}

现在改为单线程后,CPU使用率提升不少,内存占用更低。

这对我来说,真是一个意外的收获

2012-06-11
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: