1. 程式人生 > >tomcat中的執行緒問題

tomcat中的執行緒問題

看這篇文章之前,請先閱讀:
how tomcat works 讀書筆記 十一 StandWrapper 上 地址如下:
http://blog.csdn.net/dlf123321/article/details/41247693

在tomcat中,使用者的一個請求會被一個servlet來處理。
那麼當第一個人請求servletA時,它會在tomcat內部的類載入器中載入,得到一個servletA類的例項。
那個第二個人請求servletA時,又怎麼辦呢?是再得到一個新的例項還是怎麼著?
話不多說看程式碼
public Servlet allocate() throws ServletException {

        // If not SingleThreadedModel, return the same instance every time
        if (!singleThreadModel) {

            // Load and initialize our instance if necessary
            if (instance == null) {       // 如果instance為null 就呼叫loadServlet
                synchronized (this) {     // 返回一個新的
                    if (instance == null)
                            instance = loadServlet();
                }
            }

            if (!singleThreadModel) {        //如果已經有instance了 直接返回就ok
                countAllocated++;
                return (instance);
            }

   }

     synchronized (instancePool) {          //能執行到這裡,說明一定是實現了singleThreadModel

            while (countAllocated >= nInstances) {       //會給池中不斷地放置servlet
                if (nInstances < maxInstances) {
                        instancePool.push(loadServlet());
                        nInstances++;
                   
                } else {
                        instancePool.wait();  
                }
            }
            countAllocated++;
            return (Servlet) instancePool.pop();  //最後返回頂上的一個

        }
所以我們能得出一個結論,如果servlet沒有實現singleThreadModel,那麼第一次請求它時,返回一個新的,第二次就還是它本身了。如果實現了singleThreadModel,tomcat會維持一個servlet池,每次請求,都給你一個池裡的物件。

如果你看完了我文章開頭推薦的部落格,應該就明白了為什麼SingleThreadModel會被廢棄了。

那麼說到底,如果沒有SingelThreadModel,多執行緒的問題怎麼辦?
既然問的了這裡,那我就得先問一個問題了:如果是多執行緒,能有什麼問題?
請參考
http://www.cnblogs.com/gw811/archive/2012/09/07/2674859.html

另外在上面的文章中,如果我們只使用區域性變數而不用例項變數,就可以不用synchronized(this){} 這個保護。
通過上面的閱讀我們知道
解決執行緒問題的最好方法就是避免使用servlet類的內部變數。但這是一種非語法級的保護措施,程式設計師還是可能會犯這個錯誤的。

因此最好的方法就是引入ThreadLocal模式。這個模式,我們在後面會再講。

參考資料


相關推薦

Java多執行程式設計執行的同步與互斥/執行安全/Java鎖

摘要:多執行緒三個特徵:原子性、可見性以及有序性.&gt;執行緒的同步與互斥?(同步執行緒與非同步執行緒,執行緒同步和非同步問題)&nbsp;&nbsp;1.同步:假設現有執行緒A和執行緒B,執行緒A需要往緩衝區寫資料,執行緒B需要從緩衝區讀資料,但他們之間存在一種制約

專案執行原來是這麼使用的(詳解)

實現執行緒同步的幾種方式 1.同步方法 即有synchronized關鍵字修飾的方法。 由於java的每個物件都有一個內建鎖,當用此關鍵字修飾方法時, 內建鎖會保護整個方法。在呼叫該方法前,需要獲得內建鎖,否則就處於阻塞狀態。 程式碼如: public synchro

沉澱再出發:java執行池解析

沉澱再出發:java中執行緒池解析 一、前言    在多執行緒執行的環境之中,如果執行緒執行的時間短但是啟動的執行緒又非常多,執行緒運轉的時間基本上浪費在了建立和銷燬上面,因此有沒有一種方式能夠讓一個執行緒執行完自己的任務之後又被重複使用呢?執行緒池的出現就是為了解決這個問題。到了現在

Java執行池基本api及其作用

1.執行緒池相關的類 2.重要類的api及其方法 Executors.newCachedThreadPool() 建立一個可快取的執行緒池 Executors.newSingleThreadExecutor();建立一個只有一個執行緒執行的 不可修改的執行緒池  

Springboot打包放入tomcat執行

pom.xml調整 1.1 打包方式修改 <packaging>jar</packaging> 變更為 <packaging>war</packaging> 1.2. 新增依賴 重點:scope是provided <d

Java執行的同步非同步、以及執行的安全

  什麼是執行緒同步?     這裡的“同”是協同的意思,並不是共同。那麼就很好理解同步了,就是一起操作但並不是同時操作。比如流水線組裝汽車,可以視作一個執行緒,只有裝好了上一步的門,才可以裝下一步的門窗玻璃。沒有裝門能裝上玻璃嗎?顯然不行。所以執

java程式執行cpu使用率計算

原文地址:https://www.imooc.com/article/27374 最近確實遇到題目上的剛需,也是花了一段時間來思考這個問題。 cpu使用率如何計算     計算使用率在上學那會就經常算,不過往往計算的是整個程式執行的時間段,現

Java執行安全的單例模式

Java中執行緒安全的單例 深入研究Servlet執行緒安全性問題 來源:網路整理 作者:2017年12月01日 14:03 0 分享 訂閱 關鍵詞:Servlet執行緒     Servlet(Server Applet)是Java Servle

Linux執行使用詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

常見4執行

執行緒池能有效的處理多個執行緒的併發問題,避免大量的執行緒因為互相強佔系統資源導致阻塞現象,能夠有效的降低頻繁建立和銷燬執行緒對效能所帶來的開銷。真正執行緒池的實現是通過ThreadPoolExecutor,ThreadPoolExecutor通過配置不同的引數配置來建立執行緒池。下面簡單的介紹一下各個執行緒

java執行池的生命週期

執行緒池生命週期包括: RUNNING:接收新的任務並處理佇列中的任務 SHUTDOWN:不接收新的任務,但是處理佇列中的任務 STOP:不接收新的任務,不處理佇列中的任務,同時中斷處理中的任務 TIDYING:所有的任務處理完成,有效的執行緒數是0 TERMINATED:termin

Java執行池,你真的會用嗎

轉載自   Java中執行緒池,你真的會用嗎 在《深入原始碼分析Java執行緒池的實現原理》這篇文章中,我們介紹過了Java中執行緒池的常見用法以及基本原理。 在文中有這樣一段描述: 可以通過Executors靜態工廠構建執行緒池,但一般不建議這樣使用。 關於這個

在JAVA執行到底起到什麼作用!

這是javaeye上非常經典的關於執行緒的帖子,寫的非常通俗易懂的,適合任何讀計算機的同學. 執行緒同步 我們可以在計算機上執行各種計算機軟體程式。每一個執行的程式可能包括多個獨立執行的執行緒(Thread)。 執行緒(Thread)是一份獨立執行的程式,有自己專用的執行棧。執行緒有可能和其他執行緒

java執行池的生命週期與執行中斷

執行緒池生命週期包括: RUNNING:接收新的任務並處理佇列中的任務 SHUTDOWN:不接收新的任務,但是處理佇列中的任務 STOP:不接收新的任務,不處理佇列中的任務,同時中斷處理中的任務 TIDYING:所有的任務處理完成,有效的執行緒數是0 TE

Junit單元測試+aop+spring+執行池,在進行Junit測試時切面執行池內呼叫的方法不執行

一、問題背景: 寫了一個切面,指向某service包下的所有類及方法,當該service包下方法被呼叫時切面執行,切面中用了執行緒池ExecutorService pool = Executors.newFixedThreadPool(5);執行緒池內呼叫了dao層的方法。 二、問題描述:單

C++ 執行函式為靜態函式 及 類成員函式作為回撥函式

 執行緒函式為靜態函式:   執行緒控制函式和是不是靜態函式沒關係,靜態函式是在構造中分配的地址空間,只有在析構時才釋放也就是全域性的東西,不管執行緒是否執行,靜態函式的地址是不變的,並不在執行緒堆疊中static只是起了一個裝飾的作用,所以二者並沒有必然的關係   執行緒也是一種

java執行安全和非執行安全的集合

  執行緒安全 非執行緒安全 Collection Vector ArrayList、LinkedList   H

Java執行有幾種狀態

線上程的生命週期裡,執行緒總共有6種狀態,這是Java5之後在公共內部列舉類Thread.State裡面宣告的。他們分別是 NEW:新建,表示的是執行緒被創建出來但還未被投入使用。 RUNNABLE:就緒,這個執行緒已經在JVM裡被執行,有可能是正在執行也有可能是等待CPU分配資源進入了就緒

java執行同步的幾種方法

方法一: 使用synchronized關鍵字  由於java的每個物件都有一個內建鎖,當用此關鍵字修飾方法時, 內建鎖會保護整個方法。在呼叫該方法前,需要獲得內建鎖,否則就處於阻塞狀態。 注: synchronized關鍵字也可以修飾靜態方法,此時如果呼叫該靜態方法,將會

java執行的建立

java中執行緒的建立 package com.carlinfo.bigdata; /** * java中執行緒的建立 */ public class Ops3 { public static void main(String[] args) { /**