Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何通过ThreadId检测线程的结束?_Java_Servlets - Fatal编程技术网

Java 如何通过ThreadId检测线程的结束?

Java 如何通过ThreadId检测线程的结束?,java,servlets,Java,Servlets,在这里谈论Java servlet。。。我正在创建自己的“每请求上下文”,并希望将“每请求上下文”对象绑定到Thread.currentThread().getId()值 我计划在用户调用基于每个请求的函数时检查当前线程ID,并自动从该线程ID的哈希表中获取上下文对象,而不是到处传递该上下文对象 我会像这样使用代码 public void doPost(HttpServletRequest request, HttpServletResponse response) throws Servle

在这里谈论Java servlet。。。我正在创建自己的“每请求上下文”,并希望将“每请求上下文”对象绑定到Thread.currentThread().getId()值

我计划在用户调用基于每个请求的函数时检查当前线程ID,并自动从该线程ID的哈希表中获取上下文对象,而不是到处传递该上下文对象

我会像这样使用代码

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(long)

有什么想法吗?

A似乎非常适合你的使用。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(); }
}
private static final ThreadLocal userContext=new ThreadLocal();
public void doPost(HttpServletRequest请求、HttpServletResponse响应)
抛出ServletException、IOException{
MyFramework.EnterContext();
试一试{
UserContext=UserContext.get();
//如果您之前在此线程中使用了set方法
//将使用get返回线程本地上下文
}
最后{MyFramework.ExitContext();}
}

至于您的另一个问题,您可以使用观察者模式,并在线程完成任务时发出通知

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


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

我认为您在这方面做得不正确。首先,我认为你用线程做的是错误的。您应该在servlet上下文中工作。ServletContext适用于使用系统的所有用户。HttpSession适用于当前用户。我需要的是“每个请求”上下文,换句话说,同一用户的多个请求。。。我试图避免我的框架可以在页面上的多个位置使用并异步加载的情况,我不希望它们同时执行,因为使用的信息是每个请求的信息。我宁愿告诉他们,如果他们有问题,他们应该尝试一下。感谢你的建议,在对ThreadLocal的想法进行了更多的研究之后,我对这个答案翻了个跟头。事实证明,Weblogic正在使用一个线程池来执行线程,这样线程就不会真正消亡。当weblogic(显然还有tomcat)将线程放回池中时,它们不会清除ThreadLocal变量。只有在重新部署应用程序后,它才会清理它们。最后,唯一安全的方法是创建一个servlet过滤器。(仅供参考)Servlets 3.0允许您自动注册它们,因此不需要web.xml。我明白了,这是有道理的!不知道自动注册,听起来很有用!仅供参考,该线程是由Tomcat创建的,而不是由我创建的,因此任务是doPost(),对于用户来说,像我提到的那样进行最后的尝试是有意义的。。。但我真的认为你在这里提到的会起作用。不过有一个问题,我似乎不需要用这个方法来观察,因为它实际上是连接到线程的,所以当线程消失时,它应该自动将其收集起来。在你的例子中,这是正确的吗?或者我需要在某个时候将userContext设置为null吗?我发现专门针对tomcat的信息说,如果ThreadLocal未被处理,则tomcat>=6.0.24的新版本将警告关闭它,这对我来说已经足够了。>=7.0.6实际上会自动修复它。所以,使用这个解决方案并指导使用try finally应该会很好。请参阅对答案的评论,为什么我将答案翻到了rodion。我仍然使用ThreadLocal,但它不能自动清洁。