欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

请求、线程和方法执行

程序员文章站 2022-03-02 22:45:02
...

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方法中,不要在静态或实例变量中存储请求或相应对象

相关标签: JavaWeb