线程是执行的单元,因此多个线程可以同时执行相同的代码。如果多个线程同时在一个对象/实例上执行,它们将共享实例变量。每个线程都有其自己的局部变量,但是不传递参数就很难在对象之间共享它们。
最好通过一个例子来解释。假设您有一个Servlet,该Servlet可以获取已登录的用户,然后执行一些代码。
doGet(HttpServletRequest req, HttpServletResponse resp) { User user = getLoggedInUser(req); doSomething() doSomethingElse() renderResponse(resp)}
现在,如果doSomething()方法需要访问用户对象怎么办?您不能使用户对象成为实例或静态变量,因为每个线程将使用相同的用户对象。您可以将用户对象作为参数传递,但这很快就会变得混乱,并且将用户对象泄漏到每个方法调用中:
doGet(HttpServletRequest req, HttpServletResponse resp) { User user = getLoggedInUser(req); doSomething(user) doSomethingElse(user) renderResponse(resp,user)}
一个更优雅的解决方案是将用户对象放入ThreadLocal
doGet(HttpServletRequest req, HttpServletResponse resp) { User user = getLoggedInUser(req); StaticClass.getThreadLocal().set(user) try { doSomething() doSomethingElse() renderResponse(resp) } finally { StaticClass.getThreadLocal().remove() }}
现在,任何需要用户对象的代码都可以通过从本地线程中提取来获得它,而无需使用那些讨厌的额外参数:
User user = StaticClass.getThreadLocal().get()
如果使用此方法,请注意在finally块中再次删除对象。否则,用户对象可能会在使用线程池的环境中徘徊(例如Tomcat应用程序服务器)。
编辑:静态类的代码
class StaticClass { static private ThreadLocal<User> threadLocal = new ThreadLocal<>(); static ThreadLocal<User> getThreadLocal() { return threadLocal; }}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)