Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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 http请求之间是否重用请求线程?_Java_Multithreading_Google App Engine_Thread Safety_Httprequest - Fatal编程技术网

Java http请求之间是否重用请求线程?

Java http请求之间是否重用请求线程?,java,multithreading,google-app-engine,thread-safety,httprequest,Java,Multithreading,Google App Engine,Thread Safety,Httprequest,我有一个java appengine应用程序,带有true。我知道多个线程将在一个实例上运行,处理多个并发请求。我理解代码必须是线程安全的,即没有全局静态变量 我不明白的是,当请求结束时,线程是否被终止,或者在处理完另一个传入请求后,同一个线程是否可以用来处理另一个传入请求 为什么这很重要?一些细节: 我有一个带有线程局部变量的静态类,如下所示: public abstract class Foo { private static final ThreadLocal<Boolean

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

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

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

我有一个带有线程局部变量的静态类,如下所示:

public abstract class Foo {
    private static final ThreadLocal<Boolean> threadIsApiCall = new ThreadLocal<Boolean>();
    static {
         setIsApiCall(false);
    }
}
公共抽象类Foo{
private static final ThreadLocal threadIsApiCall=new ThreadLocal();
静止的{
setIsApiCall(假);
}
}

此变量存储此线程的当前请求是对RESTAPI的调用,还是来自我们自己的自定义客户端的调用。仅当与api路径匹配的筛选器运行时,才会设置此变量。我遇到的问题是,如果向我们的API发出请求,并且threadlocal变量设置为true,那么在后续请求(即非API请求)中,threadlocal变量仍然设置为true。您可能会怀疑由于静态初始值设定项的原因,它会被设置为false。唯一可以将其设置为true的方法仍然是如果初始化器没有运行,这使我相信线程是重用的。这是真的吗?

静态{…}只调用一次(当类第一次加载到内存中时,每个类装入器调用一次)

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

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();
         ...
    }
}
公共抽象类Foo{
private static final ThreadLocal threadIsApiCall=new ThreadLocal();
public static void yourFirstMethodInvokedByCustomClient(){
threadIsApiCall.set(false);
}
公共静态void yourFirstMethodInvokedByRESTAPI(){
threadIsApiCall.set(真);
}
公共静态无效另一个方法(){
布尔值isAPI=threadIsAPICall.get();
...
}
}

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

您只需通过记录
Thread.currentThread().getName()
来检查GAE是否回收线程


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

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