ThreadLocal的目的? [英] Purpose of ThreadLocal?

查看:101
本文介绍了ThreadLocal的目的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ThreadLocal的目的是这里声明该变量是访问包含ThreadLocal变量的对象的任何Thread的本地变量。将ThreadLocal变量作为类的成员然后将其作为Thread的本地变量而不是将本地变量赋予Thread本身有什么不同呢?

The purpose of ThreadLocal as given here states that the variable is local to any Thread accessing an object containing the ThreadLocal variable. What difference does it make, in having a ThreadLocal variable as a member of a class and then making it local to a Thread, rather than having a local variable to the Thread itself?

推荐答案

线程是一个执行单元,因此多个线程可以同时执行相同的代码。如果多个线程同时在对象/实例上执行,它们将共享实例变量。每个线程都有自己的局部变量,但很难在不传递参数的情况下在对象之间共享这些变量。

A thread is a unit of execution and so multiple thread can execute the same code at the same time. If multiple threads execute on an object/instance at the same time they will share the instance variables. Each thread will have its own local variables but it is difficult to share these across objects without passing parameters.

最好通过一个例子来解释。假设您有一个获取登录用户的Servlet,然后执行一些代码。

It is best explained by way of an example. Say you have a Servlet that gets the logged in user and then executes some code.

doGet(HttpServletRequest req, HttpServletResponse resp) {
  User user = getLoggedInUser(req);
  doSomething()
  doSomethingElse()
  renderResponse(resp)
}

现在,如果doSomething()方法需要访问用户对象会发生什么?您不能使用户对象成为实例或静态变量,因为每个线程将使用相同的用户对象。您可以将用户对象作为参数传递,但这会很快变得混乱,并将用户对象泄漏到每个方法调用中:

Now what happens if the doSomething() methods needs access to the user object? You can't make the user object an instance or static variable because each thread will then use the same user object. You could pass the user object around as a parameter but this quickly becomes messy and leaks user objects into every method call:

doGet(HttpServletRequest req, HttpServletResponse resp) {
  User user = getLoggedInUser(req);
  doSomething(user)
  doSomethingElse(user)
  renderResponse(resp,user)
}

更优雅的解决方案是将用户对象放入ThreadLocal

A more elegant solution is to put the user object into a ThreadLocal

doGet(HttpServletRequest req, HttpServletResponse resp) {
  User user = getLoggedInUser(req);
  StaticClass.getThreadLocal().set(user)
  try {
    doSomething()
    doSomethingElse()
    renderResponse(resp)
  }
  finally {
    StaticClass.getThreadLocal().remove()
  }
}

现在任何需要用户对象的代码都可以通过从本地线程中提取它来获取它,而不需要求助于那些讨厌的额外参数:

Now any code that requires the user object at any time can get hold of it by extracting it from the thread local, without needing to resort to those pesky extra parameters:

User user = StaticClass.getThreadLocal().get()

如果使用此方法,请注意在finally块中再次删除对象。否则,用户对象可能会在使用线程池(如Tomcat应用服务器)的环境中闲逛。

If you use this approach be mindful to remove the objects again in a finally block. Otherwise the user object might hang around in environments that use a Thread Pool (like Tomcat app server).

编辑:静态类的代码

class StaticClass {
  static private ThreadLocal threadLocal = new ThreadLocal<User>();

  static ThreadLocal<User> getThreadLocal() {
    return threadLocal;
  }
}

这篇关于ThreadLocal的目的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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