Mina传送数据问题

J2EE 码拜 10年前 (2015-04-15) 1568次浏览 0个评论
 
public class ServerMessageDecoder extends CumulativeProtocolDecoder {

	private final Charset charset = Charset.forName("UTF-8");
    private IoBuffer buff = IoBuffer.allocate(320).setAutoExpand(true);
    //private static int count = 0;
	@Override
	public boolean doDecode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out) throws Exception {
		...;
}

想问下,这个doDecode方法是不是线程安全的? 从我打印的log来看好像不是线程安全的… 也就是说会有多个线程调用doDeocde.
但是我在网上看的代码都是对ioBuffer数据直接处理,没有区别ioseesion.我想问下,你们是怎么处理的?

Mina传送数据问题
95分
——-从我打印的log来看好像不是线程安全的… 也就是说会有多个线程调用doDeocde.

这句话说错了,有多个线程调用并不代表就是非线程安全。是否线程安全是根据多个线程和单个线程调用的结果是否一致确定的。
ioseesion不是没用,是隐式用的,如果读不完,就把剩下的存放到iosession里。

Mina传送数据问题
引用 1 楼 fangmingshijie 的回复:

——-从我打印的log来看好像不是线程安全的… 也就是说会有多个线程调用doDeocde.

这句话说错了,有多个线程调用并不代表就是非线程安全。是否线程安全是根据多个线程和单个线程调用的结果是否一致确定的。
ioseesion不是没用,是隐式用的,如果读不完,就把剩下的存放到iosession里。

嗯,对的,我说错了

如果一次没有读完,假设这个ioseesion是A,如何保证下次来的数据是A的呢,其它线程也会写数据的..是不是自己要写同步方法维护?

Mina传送数据问题
是的,要自己写同步方法实现数据的一致性。
Mina传送数据问题
5分
从语义上看ServerMessageDecoder?这种底层的类属于功能类,本身就不应该有状态,简单的说,不应该有自己的成员变量之类的东西,所以在多线程的环境下是没有问题的。如果你把状态之类的东西放在这个类里,就理所应当没办法保证安全了
Mina传送数据问题
private final Charset charset = Charset.forName("UTF-8");
    //private IoBuffer buff = IoBuffer.allocate(320).setAutoExpand(true);
    private final AttributeKey CONTEXT = new AttributeKey(getClass(), "context");
    
	private Context getContext(IoSession session) {
		Context context = (Context) session.getAttribute(CONTEXT);
		if (null == context) {
			context = new Context();
			session.setAttribute(CONTEXT, context);
		}
		return context;
	}
    
    
	@Override
	public boolean doDecode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out) throws Exception {
		boolean complete = false;

		Context ctx = this.getContext(iosession);
		ctx.append(iobuffer);
		IoBuffer buf = ctx.getBuffer();  
        buf.flip();
        
		while (buf.hasRemaining()) {

            byte b = buf.get();
            /**
			 * CIMConstant.MESSAGE_SEPARATE 为消息界限
			 * 当一次收到多个消息时,以此分隔解析多个消息
			 */
            if (b == CIMConstant.MESSAGE_SEPARATE ) {
            
            	complete = true;
                break;
            } /*else {
                buff.put(b);
            }*/
        }
		if (complete) {
			buf.flip();
	        byte[] bytes = new byte[buf.limit()-1];
	        buf.get(bytes);
	        String message = new String(bytes, charset);
	        buf.clear();
	        ctx.reset();
	        
			System.out.println("iosessionid = " + iosession.getId() +"  &&&&&&&&&&&&& = " +message);
			SentBody body = new SentBody();

	    	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();   
	        DocumentBuilder builder = factory.newDocumentBuilder();  
	        Document doc = builder.parse(new ByteArrayInputStream(message.getBytes(charset)));
	        body.setKey(doc.getElementsByTagName("key").item(0).getTextContent());
	        NodeList items = doc.getElementsByTagName("data").item(0).getChildNodes();  
	        for (int i = 0; i < items.getLength(); i++) {  
	            Node node = items.item(i);  
	            body.getData().put(node.getNodeName(), node.getTextContent());
	        }
	        
	        out.write(body);
		}
	    return complete;
	}

	private class Context {

		private final IoBuffer innerBuffer;

		public Context() {
			innerBuffer = IoBuffer.allocate(320).setAutoExpand(true);
		}

		public void reset() {
			this.innerBuffer.clear();
		}

		public void append(IoBuffer in) {
			innerBuffer.put(in);

		}

		public IoBuffer getBuffer() {
			return this.innerBuffer;
		}
	}

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Mina传送数据问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!