非阻塞的servlet还能在线程内共享对象吗?

非墨
  • 2.1k

这个问题基本上我已经搞明白了,但好歹这是我潜水很久以来第一次提问,就留个纪念吧。


我看到 tomcat 6 开始有了非阻塞的功能,我知道以前是“单例多线程”的,如果在一次servlet中,我要在整个执行流程的后面某个方法里使用一个未经传递的参数(例如request没有传递而流经多层方法后某个方法要判断 session 里的某个属性),可以通过在一个静态类中用 Map<ThreadID,MyData> 来共享。

但是,如果改成非阻塞的模式了,是不是说无法用线程 ID 来区别请求了?例如开始我在当前线程 ID 123 下存入对象 A,执行到后面的方法里取出的时候可能线程 ID 已经是 345 了(这个我觉得不可能);如果不是前面这样,那会不会我当前线程 ID 123 还没结束,另一个处理新请求的线程 ID 有可能也是 123。

能不能详细的解释下这个非阻塞的实现方式。尤其是在 doService 方法开始,跟以前有什么不同了吗?

回复
阅读 4.4k
2 个回答

我找到一篇相关的文章 http://www.ibm.com/developerworks/cn/java/j-nioserver/ (虽然是篇老文章,但是介绍了 Servlet 中应用 NIO 的方法),从这篇文章上看,不会存在 doService 过程中调用的对象/方法处于另一个线程中(当然你自己在后面用了多线程除外),也不可能同一工作线程同时处理不同请求,只是主线程变化了而已。

BIO是:收到请求,从线程池取一个空闲线程处理请求,直到处理完成返回结果。

NIO是:收到请求,主线程将其通过管道(或类似方式)交给一个空闲的工作线程(或创建一个新线程),此时主线程又可以去处理其他请求了,工作线程在处理完后触发事件通知主线程完成,主线程再将状态/结果返回给客户端。

所以,在 doService 中在一个静态类的属性中存入 currentThreadID=>Data ,在后面的调用中通过 currentThreadID 取出前面共享的数据是仍然可行的。

不知道我的理解对不对?如不对请帮忙解疑。

先不说非阻塞, 我觉得楼主你的例子很奇怪. 你的这个变量既然是session scoped, 为什么不放在session里? 其次 "一个静态类中用 Map<ThreadID,MyData>", 这里既然对应到每一个threadid, 为什么不用ThreadLocal

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏