请求、线程和方法执行
JavaWeb高级编程读书笔记
在JavaEE中,所有的web容器中都会包含某种类型的线程池,被称为连接池或执行池。
请求与线程
请求进入web容器,会在线程池中获取可用的线程,如果找不到,则此时线程池已经达到最大线程数,该请求会进入一个先进先出的队列中,等待获取可用的线程。
在tomcat中,还有一个更高级的限制,acceptCount:定义了容器在拒绝客户端连接之前队列中可以包含的最大连接数。
当请求获取到线程时,他们的关联将会贯穿请求的整个生命周期:只要请求在由服务端的代码处理,线程就属于这个请求,当响应发送给客户端之后,线程才被释放回归线程池。
补充:请求和线程的关系不一定贯穿请求的整个生命周期… Servlet3.0中添加了异步请求上下文的概念,当Servlet处理请求时,它可以调用ServletRequest的startAsync方法,返回一个包含请求对象的javax.servlet.AsyncContext对象。然后Servlet从service方法返回,不对此请求做出响应,该请求的线程也回归线程池中… 当然该请求此时没有关闭,处于打开状态,当某些事件发生时,容器可以从AsyncContext对象中获取响应对象,并且用它来想客户端发送响应数据…这种技术主要用于长轮询
创建线程和销毁线程都会造成许多开销,影响应用的速度,所以应当采用由可复用线程组成的线程池。
线程池可以配置大小,它决定了一次性可以创建多少条连接(硬件对于连接的上下限有影响)。Tomcat中,线程池默认大小为200,而且这个数字是比较乐观的量。所以我们需要在代码中考虑并发状态下出现异常的行为。
Servlet*享资源的同步
方法中创建的对象和变量在执行时都说线程安全的。
然而:servlet中的静态变量或实例变量会被多个线程同时访问,这些资源属于共享资源,要进行同步以避免损坏资源的内容。
有时一个线程改变了某个变量的值,另一个线程却仍能读取到变量修改前的值
使用volatile关键字,保证其他线程始终都可以读取变量修改后的最终值
private voatile in ID = 1;
使用同步代码块执行关键操作
synchronized(this){
id = ID++;
//id是主键,存储到数据库中
}
补充:在Servlet方法中,不要在静态或实例变量中存储请求或相应对象
推荐阅读
-
java 线程同步方法执行与唤醒实例
-
PHP中使用cURL实现Get和Post请求的方法
-
Oracle 生成和显示执行计划的方法
-
PHP cURL初始化和执行方法入门级代码,curl初始化
-
Android 入门第十讲02-广播(广播概述,使用方法(系统广播,自定义广播,两个activity之间的交互和传值),EventBus使用方法,数据传递,线程切换,Android的系统广播大全)
-
PHP 异步执行方法,模拟多线程_PHP教程
-
react通过axios请求数据,用一个bol来判断数据是否加载完成后,渲染在页面上,不用async await和定时器的更好方法
-
C#线程 BeginInvoke和EndInvoke使用方法
-
Java终止线程实例和stop()方法源码阅读
-
Java中启动线程start和run的两种方法