如何現實servlet的單線程模式?

網上朋友的回答是加入<%@ page isThreadSafe=」false」%>這條命令。天啊,我暈!這是什麼命令?是jsp的命令啊,怎麼會加入到servlet中呢?固然了,jsp的運行實質是servlet機制,這條命令是jsp頁面告訴容器編譯「我」的時候實現單線程。那咱們看看他編譯後的servlet類和之前的servlet有什麼不一樣?沒有加入這條指令的頁面中servlet類定義是:apache

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {安全

………………………………//內部實現我們大能夠不看他。
}session

而加入這個命令以後的類定義是:jsp

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 SingleThreadModel {性能

…………………………//一樣省略實現細節.net

}線程

        我想你們應該很清楚的發現:加入<@page isThreadSafe="false">以後servlet是實現了SingleThreadModel接口的。有興趣的朋友能夠查下相關資料,其實這個接口在servlet2.4以後就廢除了。那麼爲何廢除?實現了這個接口查看代碼內容的時候卻發現什麼方法都沒添加,爲何?接口

       其實這個接口只是一個標識,讓容器改變servlet生成策略的。get

  默認的,servlet容器是隻建立servlet単實例,爲請求提供線程池,咱們爲了能保證servlet的線程安全問題而不在servlet中添加實例屬性。同步

       可是若是一個servlet實現了SingleThreadModel接口那容器在建立實例池,爲每一個求情分配實例,當用戶請求結束時將實例歸還實例池。

       這樣作真的安全嗎?非也!由於每一個請求都會分發一個servlet實例,對於同用戶下分發的不一樣的servlet來講極可能用到同一個session中的屬性數據,這樣固然出現了線程同步的問題,是不安全的!並且不一樣用戶也可能享用同一個context中的數據,也是不安全的。因而在servlet2.4中建議再也不使用這樣的設置。

  這樣一來咱們知道:若是非要實現servlet單線程那就要在servlet中實現SingleThreadModel接口,在jsp中添加<@ page isThreadSafe="false">命令。可是這是不被提倡的。

  也有網友疑問:讓servlet單線程而多實例原本不是爲了線程安全的嗎?爲何<@ page isThreadSafe=?>?的答案倒是false?

  我以爲這是個誤區,這樣設置真的是單線程嗎?那確定不是了,其實這個設置只是要容器保證同一時刻只有一個線程能在servlet的service方法中執行,由於默認的容器實例化servlet時時単實例,若是同時只有一個線程去管理這個惟一的servlet實例,那性能將是極其慢的,爲了解決這個問題,容器採起了servlet實例池的方式。每一個請求一個線程,而一個線程一個servlet。

         由於這種方式並非線程安全的,因此答案是false。

  終上所述:其實這道題目是指若是讓一個servlet實例對應一個線程,而不是一個servlet實例對應多個線程的默認方式。

相關文章
相關標籤/搜索