由于NIO连接器每个连接没有一个线程,我担心如果ThreadLocal对象在清理之前与另一个线程共享,则可能导致很难找到错误.但是,我认为这不是一个问题,因为它不是我能找到的文件警告,也没有发现任何其他帖子警告这一点.我假设NIO连接器对服务于实际请求的线程没有影响.
在我采用这个假设之前,我希望找到一些具体的证据.
解决方法
首先,您需要明确是否只是使用NIO连接器,或者您是否也在谈论Async servlet.
答案在每种情况下都会略有不同.
需要注意的主要事情是Java没有任何类型的延续,协同例程或线程重新安排.这意味着一旦你启动一个在线程上运行的代码,只有那段代码将在线程上运行直到它完成.
所以如果你有:myObject.doSomething();然后在doSomething运行的时候,它拥有对该线程的独占访问权限.该线程不会切换到其他一些代码 – 无论您使用的是什么类型的IO模型.
可能(将)会发生的是,不同的线程将被安排在不同的cpu上运行,但每个线程将运行一段代码来完成.
所以如果doSomething是:
public static final ThreadLocal<MyClass> VALUE = new ThreadLocal<MyClass>(); public void doSomething() { VALUE.set(this); try { doSomethingElse(); } finally { VALUE.set(null); } }
然后就没什么可担心的了 – doSomethingElse将运行一个线程,并且threadlocal将被设置为整个执行的正确值.
因此,简单的NIO连接器应该没有区别 – 容器将调用servlet上的服务方法,servlet将在单个线程中执行,然后最后完成所有操作.只是容器能够在处理连接时以更有效的方式处理IO.
如果您正在使用异步servlet,那么它会有所不同 – 在这种情况下,您的servlet可能会因单个请求被多次调用(因为异步模型的工作方式),并且这些调用可能位于不同的线程上,因此您可以在servlet的调用之间存储一些线程本地的东西.但是对于一次调用您的服务方法,它仍然没问题.
HTH.