`
stephen722
  • 浏览: 3709 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

是否每一个Request都由一个不同的Thread来处理

阅读更多
关于Request和Thread的关系一直有一个疑问,一般的理解就是对应每一个Request会有一个Thread来处理,问题是每一个Request是否对应的Thread是否一样,如果是一样,那么程序中在用到ThreadLocal的时候,Thread.currentThread岂不是相同,如果不一样,web 服务器是怎样做到保证用不同的Thread来处理不同的Request?

为了减少这种创建和销毁Thread的开销,一般的Web服务器在内部都有一个线程池来维护所创建的Thread,并有一个限定值控制线程池中Thread的总量。如果服务器所接受的Request数量超过线程池中Thread限制,就一部分Request处于等待状态,直到有空闲Thread才开始处理。

现在假设有一个类维护一个ThreadLocal的静态变量,每一次请求时候,都会调用ThreadLocal.get()/set() 操作, 大家都知道这些操作实际上是以Thread.currentThread为Key,取得一个对象的,问题的关键就在这里,如果每一个Request对应的Thread是一样,那么这个地方返回的对象就会是一样的,是否就混乱了呢?

现在有一个系统部署在WebLogic10下面,在第一次打开一个页面的时候,会有一个Thread被创建来处理该请求,再次打开其他页面时候,系统并不一定会创建一个新的Thread来处理,两次请求的Thread是相同的,再打开多个其他页面(超过10个),在这10多次的请求中,系统只会创建4个Thread来处理,那就是说这10多次的请求中,有一部分请求是使用相同的Thread来处理的。如果是这样的情况,上面的问题该如何解释呢?

我想Tomcat, Jboss在处理Request和Thread的时候和WebLogic应该大同小异,那么上面的问题该如何解释呢?
分享到:
评论
4 楼 Tyrion 2012-12-14  
remoteJavaSky 写道
我现在想想,是否是这样的,再每处理完一个request后,通常会清理掉ThreadLocal的变量,这通常会使用Filter来清理。也见到过这样做的,只是具体的原理还不是特别清楚

今天针对这个问题自己在Tomcat5.5.36下面测试了一下,我的结论是Tomcat的默认配置下:一个Request对应一个Thread,但一个Thread一般会处理多个Request。
我的思考是这样的:一般一个Request对象在JVM中的存活时间很短,几秒差不多了,很少有几十秒的情况。而web服务器中的线程对象在JVM中的存活时间很长,即便因为操作系统的调度会将该线程对象从running变成waiting,但目前各个商用服务器的策略是维护一个线程池,一段时间之后该线程对象还会变成waiting。
从物理时间上来说Thread生命周期远远大于Request。但从一个时间点上来看,假如一个Thread正在处理一个Request,那么该Thread不会同时还处理别的Request,即Request在Thread的生命周期内是一个一个串行执行的。

具体到ThreadLocal的使用情况来说:
我们一般使用ThreadLocal的模式是将该ThreadLocal对象作为一个类的静态变量(解决同一线程跨类跨方法访问的问题),先Set再Get,以两个Request与Thread的不同关系来说。假如这两个Request属于两个Thread则不存在问题,假如两个Request属于一个Thread,那么Request A在执行过程中先Set一个值,后再Get的是自己Set的值。Request B在执行过程中先Set一个值,此时Set的值将覆盖之前Request A已经Set的值(因为ThreadLocal的机制是在每一个线程内部以TheadLocal对象作为Key来存值,现在key没变,又塞了一个新值,所以会覆盖旧值),后Get的将是Request B的值。

这样的话楼主应该解释了楼主的疑问了。
3 楼 remoteJavaSky 2012-12-13  
我现在想想,是否是这样的,再每处理完一个request后,通常会清理掉ThreadLocal的变量,这通常会使用Filter来清理。也见到过这样做的,只是具体的原理还不是特别清楚
2 楼 Tyrion 2012-12-13  
remoteJavaSky 写道
Hi 我现在活着已经有一段时间了,纠结此问题呢,你现在该找到答案了吧,分享下吧,我都被这个问题闷死了

同求该问题的答案。。。
1 楼 remoteJavaSky 2011-08-22  
Hi 我现在活着已经有一段时间了,纠结此问题呢,你现在该找到答案了吧,分享下吧,我都被这个问题闷死了

相关推荐

    RxJava和Retrofit2的统一处理单个请求示例详解

    在描述中提到的问题是,每个网络请求都需要添加`.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).onErrorReturn()`等通用处理。为了解决这个问题,我们可以创建一个工具类`RxNet`,提供一...

    半自动化挖掘request实现多种中间件回显1

    可以通过`Thread.currentThread()`或`Thread.getThreads()`来获取线程对象,再进一步查找request。 其次,实现半自动化的反射搜索。这一步涉及到遍历全局变量的所有属性,寻找包含"Request"关键字的对象,如`...

    rock.tsf.jar

    Responder是一个从Thread类派生出来的抽象类,它有一个抽象方法doService()必须在子类中重载,开发人员根据所要实现的server的需要在此方法中进行不同的处理。 最后,MonitorPool除了实现一个工作线程对上面所描述的...

    TCP服务器多线程

    总结来说,TCP服务器多线程是一种提升并发处理能力的技术,它通过为每个客户端连接创建单独的线程,实现了服务器对多个请求的同时处理。这种方式在处理大量并发连接时,能够有效地提高服务器的响应速度和系统的整体...

    python-socket-with-thread-master_socket编程_sochet_

    总结来说,"python-socket-with-thread-master_socket编程_sochet_"项目的核心是利用Python的`socket`和`threading`模块,构建一个能够处理多个并发连接的多线程服务器。这在处理大量并发请求时,如Web服务器、文件...

    超级有影响力霸气的Java面试题大全文档

    Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑放在 method之中执行,不同的是 Stateful Session Bean 可以记录呼叫者的状态,因此通常来说,一个使用者会有一个相对应...

    okhttp拦截器

    每个拦截器都会处理请求,并将其传递给下一个拦截器,直到最后一个拦截器直接与服务器通信。响应则按照相反的顺序经过这些拦截器。 **3.4 拦截器类型** OkHttp 支持两种类型的拦截器: 1. **应用层拦截器**:通过...

    一个电梯模拟程序,模拟电梯的运行状况!包括楼层、按钮等Java.zip

    这个控制器在编程中可以被抽象为一个类,包含各种状态变量和方法来处理不同的事件。 在Java中,我们可以创建一个名为`Elevator`的类,该类应包含以下属性: 1. `currentFloor`:表示电梯当前所在的楼层。 2. `...

    Java Servlet3.0异步处理问题

    在传统的 Web 容器中,处理请求的方式是为每个 request 分配一个 thread。这意味着 thread 的创建不是没有代价的,Web 容器的 thread pool 都是有上限的。那么一个很容易预见的问题就是,在高负载情况下,thread ...

    Jmeter使用CSV Data Set Config参数化数据不重复的多次循环执行(实现多用户多次抽奖功能)

    运行完成后,可以通过“查看结果树”检查每个用户ID的请求是否正确执行,以及通过“聚合报告”来确认所有请求是否都已经成功发送。 #### 六、总结 通过使用JMeter中的CSV Data Set Config组件,我们可以轻松地实现...

    Android-使用OkHttp的AddInterceptor功能实现RxAndroidRetrofit请求结果的统一处理

    定义一个全局错误处理方法,可以在此处根据错误类型进行不同的处理,如显示错误信息、重新登录、网络重连等。 ```java private void handleError(Throwable error) { if (error instanceof HttpException) { // ...

    计算机网络原理实验报告.pdf

    每个连接到服务器的客户端请求都会由一个新的线程处理,这样可以确保服务器能同时处理多个请求,提高服务效率。`ConnectionThread`类继承自`Thread`类,表示每个客户端连接都会创建一个这样的线程。通过`Socket`对象...

    Servlet3.0 异步处理 页面推送 Comet 实例

    Servlet3.0是Java EE平台中的一个重要更新,它引入了许多新特性,其中一项重大改进就是对异步处理的支持。这项特性使得服务器可以处理长时间运行的任务,而不会阻塞其他请求,提高了系统的响应能力和效率。本实例...

    Linux网络编程之IO复用循环服务器.doc

    这样,所有已连接的客户端套接字都集中在一个集合里,等待进一步处理。 业务处理线程则通过`select()`函数轮询这个套接字集合,`select()`可以监控多个文件描述符(在本例中是客户端套接字),等待数据到达。一旦有...

    学习java跟着做的一个小游戏,顺便练习一下如何使用GitHub.zip

    1. **版本控制**:GitHub是一个分布式版本控制系统,项目中每个提交都记录了代码的修改历史,便于团队协作和追踪问题。 2. **分支管理**:在开发过程中,开发者可能创建了多个分支进行新功能的开发或修复bug,然后...

    c++实现的一个小型的http服务器

    每个客户端连接可以分配一个独立的线程,这样服务器可以同时处理多个请求。C++11引入了std::thread库,使得多线程编程变得更加方便。 6. **内存管理和错误处理**:在处理过程中,服务器必须有效地管理内存,避免...

    Web并发模型粗浅探讨

    并行则是指真正的同时进行多任务处理,这通常需要多核CPU来支持,每个核可以独立处理不同的任务,而不会相互干扰。 吞吐量是衡量系统性能的关键指标之一,通常用来衡量单位时间内服务器处理的请求数量,以request/...

    Android-Android异常捕获以及上传到服务器

    在Android应用开发中,异常处理是一项至关重要的任务,它确保了程序在遇到错误时能够以优雅的方式退出,而不是崩溃,从而提高用户体验。本教程将详细讲解如何在Android中实现异常捕获并将其上传到服务器。 首先,...

Global site tag (gtag.js) - Google Analytics