ThreadLocal是否可以安全地与Tomcat NIO Connector一起使用 [英] Is ThreadLocal safe to use with Tomcat NIO Connector

查看:206
本文介绍了ThreadLocal是否可以安全地与Tomcat NIO Connector一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在负载测试期间测试Tomcat NIO连接器时,我们想到了这一点。我使用ThreadLocal另外我使用Spring,我知道在几个地方它也使用它。

This just came to mind when testing the Tomcat NIO connector during my load tests. I make use of ThreadLocal's additionally I use Spring, which I know in several places it also makes use of it.

由于NIO连接器没有每个连接的线程,我担心如果ThreadLocal对象与之前的另一个线程共享,可能会导致很难找到错误已被清理干净。但是,我认为这不是一个问题,因为它不是我能找到的文件警告,也没有发现任何其他帖子警告这一点。我假设NIO连接器对服务于实际请求的线程没有影响。

Since the NIO connector does not have a thread per connection, I worry that it may result in very hard to find bugs if a ThreadLocal object was shared with another thread before it had been cleaned up. However, I assume that this is not an issue as it is not a documented warning that I could find, nor have I found any other posts warning about this. I assume that the NIO connector has no effect to the threads that serve the actual requests.

在我采用这个假设之前,我希望找到一些具体的证明。

Before I go with this assumption, I was hoping to find some concrete proof.

推荐答案

只有熟悉Tomcat代码的人才能给你一个具体的答案,但我会尝试一个木制代码:)

Only someone familiar with the Tomcat code will be able to give you a concrete answer, but I'll try a wooden one :)

首先,您需要清楚是否只是简单地使用NIO连接器,或者您是否也在谈论Async servlet。
答案在每种情况下都会略有不同。

Firstly, you need to be clear whether you mean simply using NIO connectors or whether you're also talking about Async servlets. The answer will be slightly different in each case.

需要注意的主要问题是Java没有任何类型的延续,例程或线程重新安排。这意味着一旦你启动了一个在线程上运行的代码, 那条代码将在线程上运行直到它完成。

The main thing to be aware of is that Java doesn't have any sort of continuations, co-routines or thread-rescheduling. Which means that once you launch a piece of code running on a thread, only that piece of code will run on the thread until it completes.

所以如果你有: myObject.doSomething(); 那么 doSomething 运行,它具有该线程的独占访问权限。该线程不会切换到其他一些代码 - 无论您使用的是什么类型的IO模型。

So if you have: myObject.doSomething(); then for the time doSomething runs, it has exclusive access to that thread. The thread is not going to switch to some other piece of code - regardless of what sort of IO model you're using.

可能(将)会发生什么不同线程将被安排在不同的CPU上运行,但每个线程将运行一段代码完成。

What might (will) happen is that different threads will be scheduled to run on different CPUs, but each thread will run one piece of code to completion.

所以如果 doSomething 是:

public static final ThreadLocal<MyClass> VALUE = new ThreadLocal<MyClass>();
public void doSomething() {
  VALUE.set(this);
  try {
    doSomethingElse();
  } finally {
    VALUE.set(null);
  }
}

然后没有什么可担心的 - doSomethingElse 将运行一个线程,并且threadlocal将被设置为整个执行的正确值。

then there's nothing to worry about - doSomethingElse will run one a single thread and the threadlocal will be set to the right value for the whole execution.

所以一个简单的NIO连接器应该没有区别 - 容器将在servlet上调用 service 方法,servlet将在单个线程中执行,然后最后完成所有操作。只是容器能够以更有效的方式处理IO,因为它处理连接。

So a simple NIO connector should make no difference - the container will call the service method on the servlet, the servlet will execute in a single thread, and then at the end it's all done. It's just that the container is able to process the IO in a more efficient way as it handles the connections.

如果你使用异步servlet那么它有点不同 - 在这种情况下,您的servlet可能会被多次调用一次请求(由于异步模型的工作方式),并且这些调用可能位于不同的线程上,因此您无法在调用您的调用之间的某个线程中存储某些内容servlet的。但是对于一次调用您的服务方法,它仍然可以。

If you're using async servlets then it's a little different - in that case your servlet might get called multiple times for a single request (because of the way the asynchronous model works), and those calls might be on different threads, so you can't store something in a thread-local between invocations of your servlet. But for a single call to your service method, it's still fine.

HTH。

这篇关于ThreadLocal是否可以安全地与Tomcat NIO Connector一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆