mina线程总结
来源:互联网 发布:兴奋剂 知乎 编辑:程序博客网 时间:2024/06/18 08:52
今天对mina的线程做了些实验,先上代码
MyCodecFactory:
public class MyCodecFactory implements ProtocolCodecFactory{ ProtocolEncoderAdapter encoder = new MyEncoder(); ProtocolDecoder decoder = new MyDecoder(); public ProtocolDecoder getDecoder(IoSession session) throws Exception { return decoder; } public ProtocolEncoder getEncoder(IoSession session) throws Exception { return encoder; }}
MyDecoder:
public class MyDecoder extends ProtocolDecoderAdapter{ @Override public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { int id = in.getInt(); int len = in.getInt(); byte [] dst = new byte [len]; in.get(dst); String name = new String(dst,"GBK"); Item item = new Item(); item.setId(id); item.setName(name); out.write(item); } }
MyEncoder:
public class MyEncoder extends ProtocolEncoderAdapter{ public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { Item item = (Item) message; int byteLen = 8 + item.getName().getBytes("GBK").length; IoBuffer buf = IoBuffer.allocate(byteLen); buf.putInt(item.getId()); buf.putInt(item.getName().getBytes("GBK").length); buf.put(item.getName().getBytes("GBK")); buf.flip(); out.write(buf); }}ClientSessionHandle:
public class ClientSessionHandle implements IoHandler{ @Override public void sessionCreated(IoSession session) throws Exception { System.out.println("client sessionCreated" + System.currentTimeMillis()); } @Override public void sessionOpened(IoSession session) throws Exception { System.out.println("client sessionOpened" + System.currentTimeMillis()); } @Override public void sessionClosed(IoSession session) throws Exception { System.out.println("client sessionClosed" + System.currentTimeMillis()); } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("client sessionIdle" + System.currentTimeMillis()); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { cause.printStackTrace(); System.out.println("client exceptionCaught" + System.currentTimeMillis()); } @Override public void messageReceived(IoSession session, Object message) throws Exception { System.out.println("recieveMsg:" + System.currentTimeMillis()); } @Override public void messageSent(IoSession session, Object message) throws Exception {// Thread.sleep(3000); System.out.println("client messageSent" + System.currentTimeMillis()); }}ServerSessionHandle:
public class ServerSessionHandle implements IoHandler{ @Override public void sessionCreated(IoSession session) throws Exception { System.out.println("server sessionCreated" + System.currentTimeMillis()); } @Override public void sessionOpened(IoSession session) throws Exception { System.out.println("server sessionOpened" + System.currentTimeMillis()); } @Override public void sessionClosed(IoSession session) throws Exception { System.out.println("server sessionClosed" + System.currentTimeMillis()); } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("server sessionIdle" + System.currentTimeMillis()); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { cause.printStackTrace(); System.out.println("server exceptionCaught"); } @Override public void messageReceived(IoSession session, Object message) throws Exception {// Thread.sleep(3000); System.out.println("server recieveMsg:" + System.currentTimeMillis()); } @Override public void messageSent(IoSession session, Object message) throws Exception { System.out.println("server messageSent" + System.currentTimeMillis()); }}Client:
public class Client{ public static void main(String[] args) throws IOException { IoConnector connector = new NioSocketConnector(); connector.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new MyCodecFactory())); connector.setHandler(new ClientSessionHandle());// connector.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool())); ConnectFuture future = connector.connect(new InetSocketAddress(8888)); future.awaitUninterruptibly(); IoSession session = future.getSession(); Item item = new Item(); item.setId(1); item.setName("aaa"); session.write(item); session.write(item); session.write(item); session.write(item); session.write(item); }}Server:
public class Server{ public static void main(String[] args) throws IOException { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new MyCodecFactory()));// acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool())); acceptor.setHandler(new ServerSessionHandle()); acceptor.bind(new InetSocketAddress(8888)); }}
mina简介
mina的工作模式如下图所示
acceptor用于处理客户端的连接,当有客户端连接时,将连接交给Processor处理,Process是多线程的,在内部由一个线程池来处理,线程的个数由创建Acceptor时参数指定,默认是cpu核数加1,filter主要用来对消息进行过虑,经常用来做编码解码,消息经过filter过虑之后由handler来处理,我们做开发时业务也都是在handler层做。
一个客户端连接到服务器端之后,由一个且只会有一个processor来处理。服务器启动后,processor的数量是0,每一个客户端连接上来,就会创建一个Processor,直到达到最高数量。当所有的processor都在处理客户端的信息时,后续的客户端都会产生阻塞,所以当同时处理消息量过多,io不多,但是handler处理时间较长时,我们就要采用另一种处理方式 ,即把handler放在另外的线程来处理,代码如下:
acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
实验过程
这篇文章的重点内容是来实验mina的线程问题,主要是processor和handler使用不同线程处理客户端消息的情况,实验内容是客户端连接成功之后连续发送5条消息
(1)客户端与服务器端都不采用handler单独线程,客户端ClientSessionHandle的messageSent方法延迟3s发送,结果如下,消息是排着队发送
客户端结果
client sessionCreated1384482297824
client sessionOpened1384482297825
client messageSent1384482300829
client messageSent1384482303829
client messageSent1384482306830
client messageSent1384482309830
client messageSent1384482312830
服务器结果
server sessionCreated1384482297813
server sessionOpened1384482297813
server recieveMsg:1384482297828
server recieveMsg:1384482300829
server recieveMsg:1384482303830
server recieveMsg:1384482306830
server recieveMsg:1384482309830
(2)客户端采用handler单独线程,客户端ClientSessionHandle的messageSent方法延迟3s发送,结果如下,消息是连接成功之后延迟3s并行发送出去
客户端结果
client sessionCreated1384482710537
client sessionOpened1384482710538
client messageSent1384482713542
client messageSent1384482713542
client messageSent1384482713542
client messageSent1384482713542
client messageSent1384482713542
服务器结果
server sessionCreated1384482710525
server sessionOpened1384482710526
server recieveMsg:1384482710541
server recieveMsg:1384482710541
server recieveMsg:1384482710542
server recieveMsg:1384482710542
server recieveMsg:1384482710542
(3)客户端采用handler单独线程,客户端连接成功之后不延迟3s直接发送5条消息,服务器端ServerSessionHandle延迟3s接收,结果如下,5条消息是一起发出,但服务器端每3s处理一条消息,jconcle监控发现只有一个processor线程,由此验证了:一个客户端只会有一个processor进行处理,handler与processor同一线程的情况下,消息是排队的。
客户端结果
client sessionCreated1384482908375
client sessionOpened1384482908377
client messageSent1384482908380
client messageSent1384482908380
client messageSent1384482908381
client messageSent1384482908381
client messageSent1384482908381
服务器结果
server sessionCreated1384482908372
server sessionOpened1384482908372
server recieveMsg:1384482911381
server recieveMsg:1384482914382
server recieveMsg:1384482917382
server recieveMsg:1384482920382
server recieveMsg:1384482923382
(4)客户端与服务器端都采用handler单独线程,客户端连接成功之后不延迟3s直接发送5条消息,服务器端ServerSessionHandle延迟3s接收,结果如下,5条消息是一起发出,服务端延迟3s后一起处理了5条消息,jconcle监控发现还是只有一个processor线程,但还会创建另外5个线程,这五个线程各自处理了一条消息,由此验证了:一个客户端只会有一个processor进行处理,processor接收到客户端的消息之后,放到了handler处理线程中处理。
客户端结果
client sessionCreated1384483318084
client sessionOpened1384483318086
client messageSent1384483318088
client messageSent1384483318089
client messageSent1384483318089
client messageSent1384483318089
client messageSent1384483318089
服务器结果
server sessionCreated1384483318081
server sessionOpened1384483318082
server recieveMsg:1384483321090
server recieveMsg:1384483321091
server recieveMsg:1384483321091
server recieveMsg:1384483321091
server recieveMsg:1384483321091
- mina线程总结
- Mina总结
- mina总结
- mina总结
- mina的线程模型
- mina 线程模型配置
- Mina 线程模型分析
- mina线程模型
- mina 学习3-mina线程模型
- MINA框架使用总结
- MINA框架使用总结
- Mina使用问题总结
- MINA框架使用总结
- MINA框架使用总结
- Mina框架总结
- MINA框架使用总结
- MINA框架使用总结
- Mina使用总结
- spring+apache shiro demo
- MyEclipse6.0编译后的类无法自动发不到WebRoot/WEB-INF/classes文件夹下(转)
- Scrum敏捷开发&管理--计划启动
- 一个懦弱的IT人
- VC 如何使程序运行后自己删除自己
- mina线程总结
- Linux文件系统
- 你看透了这些,别人就看不透你
- 电脑培训知识-网站第一屏(幕)应该如何设计
- libtorrent分析
- Android 源码编译结果
- Ormlite在一般java环境(android)中操作Sqlite
- oracle分区
- php导出word格式数据的代码分享