3

在这里谈论 Java Servlet... 我正在创建自己的“每个请求上下文”,并且希望将“每个请求上下文”对象与 Thread.currentThread().getId() 值联系起来。

我计划在用户调用基于 Per Request 的函数并自动从该 threadId 的哈希表中获取 Context 对象时检查当前 threadid,而不是到处传递这个 context 对象。

我会使用这样的代码..

public void doPost(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException
{
    MyFramework.EnterContext();
    try {
        // do stuff here that leads to other classes on the same thread
        // Access current context via static MyFramework.getCurrentContext()
    }
    finally { MyFramework.ExitContext(); }
}

但是,我想自动保护我的应用程序免受任何不调用 ExitContext() 的潜在用户的影响。在 C# 中有一个用于 onexit 的线程对象上的事件处理程序...(认为我错了)有没有办法在线程退出时检测或轮询?我目前只存储threadId(长)。

有任何想法吗?

4

2 回答 2

1

ThreadLocal似乎非常适合您的使用。ThreadLocal 对象可以提供一种方法来存储每个线程的变量。此类的内部工作原理与您所描述的非常相似,它使用映射来提供线程局部变量。

这样的事情应该可以解决问题:

private static final ThreadLocal<UserContext> userContext = new ThreadLocal<UserContext>();

public void doPost(HttpServletRequest request, HttpServletResponse response) 
              throws ServletException, IOException {
    MyFramework.EnterContext();
    try {
       UserContext context = userContext.get();
       //if you used the set method in this thread earlier
       //a thread local context would be returned using get
    }
    finally { MyFramework.ExitContext(); }
}

至于您的其他问题,您可以使用观察者模式并在线程完成其任务时通知。

于 2012-04-26T00:42:13.517 回答
1

不幸的是,Java 中没有为线程内置这样的特性。此外,线程 id 只保证在任何时候都是唯一的,但最终可以在线程死亡时重用(来自文档)。但是,您使用的 servlet 框架可能正在实现此类功能(只是推测)。

我建议您实现一个 servlet 过滤器,并告诉您的用户将其包含在他们的web.xml. 有了这个,您可以确保客户端代码始终正确地包装在您的线程上下文中。

于 2012-04-26T00:49:46.930 回答