请求、线程和方法执行

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cjmust/article/details/83181499

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

猜你喜欢

转载自blog.csdn.net/cjmust/article/details/83181499