最近一直研究MINA来写服务程序,发现了 一些问题,在此记一下,和大家共享,不对之处,多多指教。
MINA可以由我们添加一个线程池,如果没有的话,它会自己产生一个线程池供自己使用,mina的效率还是很不错的。我们可以发现setHandler时候,只添加一个IoHandler的对象,也就是说,整个服务器程序只有一个处理器实例。那么,就很容易产生线程安全的问题,因为服务器程序是高并发的,一对多的。
仔细发现,我们添加Filter的时候,也只有一个实例,在自定义过滤器时,Decoder和Encoder也要注意线程安全。
原来他们是被用来被其他的外壳来调用这几个实例的方法。使用的时候将不同的参数传递给IoHandler等实例的public方法,这样避免为不同的连接new一样的处理器,虽然会产生一些问题。可以确定IoSession是多实例的,因此我们可以好好利用它的setAttribute方法来保存我们希望下一次还能使用的对象。仔细想想,这和Servlet的那中使用多线程(Web容器),单实例(Servlet实例)的模式是多么的相似。
解决方法很简单:
1.尽量不要使用成员变量(即使用了,也要保证这个成员也是线程安全的)
2.如果有需要保存的数据,请使用IoSession的setAttribute方法,这个方法很好用,MINA很贴心的。
3.使用ThreadLoacl来保存数据(建议使用IoSession)
以上是我的小小总结,有的同学可能会问:为什么不使用synchronized,服务器程序要求的是效率,高并发,但是你加一个互斥,这个。。。。。。。你懂的