【问题标题】:Are request threads reused between http requests?http请求之间是否重用了请求线程?
【发布时间】:2012-08-24 17:20:18
【问题描述】:

我有一个 true 的 java appengine 应用程序。我知道多个线程将在处理多个并发请求的单个实例上运行。我知道代码必须是线程安全的,即没有全局静态变量。

我不明白的是线程是否在请求结束时被杀死,或者同一线程是否可以在处理完另一个传入请求后用于处理另一个传入请求。

为什么这很重要?一些细节:

我有一个带有线程局部变量的静态类:

public abstract class Foo {
    private static final ThreadLocal<Boolean> threadIsApiCall = new ThreadLocal<Boolean>();
    static {
         setIsApiCall(false);
    }
}

这个变量存储当前对该线程的请求是调用我们的rest api还是来自我们自己的自定义客户端的调用。只有在匹配我们的 api 路径的过滤器运行时,才会设置此变量。我遇到的问题是,如果向我们的 API 发出请求,并且 threadlocal 变量设置为 true,那么在后续请求(不是 api 请求)上,threadlocal 变量仍设置为 true。您会怀疑它会因为静态初始化程序而设置为 false。仍然可以将其设置为 true 的唯一方法是,如果初始化程序没有运行,这导致我相信线程被重用。这是真的吗?

【问题讨论】:

    标签: java multithreading google-app-engine thread-safety httprequest


    【解决方案1】:

    static{...} 仅被调用一次(每个类加载器,当类首次加载到内存中时)。

    您需要为每个线程设置 theadlocal 值:

    public abstract class Foo {
        private static final ThreadLocal<Boolean> threadIsApiCall = new ThreadLocal<Boolean>();
    
        public static void yourFirstMethodInvokedByCustomClient() {
             threadIsApiCall.set(false);
        }
    
        public static void yourFirstMethodInvokedByRESTAPI() {
             threadIsApiCall.set(true);
        }
    
        public static void anotherLaterMethod() {
             boolean isAPI = threadIsAPICall.get();
             ...
        }
    }
    

    【讨论】:

    • 感谢您的澄清,但是线程是否被重用了?因为如果不是,那么理论上应该可以:
    • if (threadAdmin.get() != null) { return threadAdmin.get().booleanValue(); } 否则 { 返回假; ... 然后只在 APIFilter 中将值设置为 true。这是我目前拥有的,但它不起作用。这就是为什么我认为线程正在被重用。因为如果它是一个新线程,那么 .get() 将返回 null(因为它还没有为客户端调用设置)。
    • 是的,根据其他答案,可以根据您的服务器重用线程。我应该澄清一下,在 anotherLaterMethod() 中获取线程本地仅在同一个 http 请求处理上下文中有效,它不会在请求之间存储值。
    【解决方案2】:

    线程重用是 servlet 实现的一个实现细节。线程通常通过线程池重用。这通常可以通过 servlet 配置进行配置。不幸的是,GAE 并非如此。

    您可以通过记录Thread.currentThread().getName() 来简单地检查 GAE 是否回收线程。

    由于可能的线程重用,在 servlet 中使用 ThreadLocal 总是一个坏主意。如果您需要在请求范围内存储一些数据,请使用servletRequest.setAttribute(..)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-13
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 2018-08-17
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      相关资源
      最近更新 更多