點選檢視代碼
public class DiyTomcat {
private int port = 8080;
public static final HashMap<String, DiyServlet> SERVLET_MAPPING = new HashMap<>();
public static final HashMap<String,String> URL_MAPPING = new HashMap<>();
private static ThreadPoolExecutor threadPoolExecutor;
static {
loadServlet();
initExecutors();
}
// 線程池化
private static void initExecutors() {
int corePoolSize = 10;
int maximumPoolSize = 50;
long keepAliveTime = 100L;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
threadPoolExecutor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory,
handler
);
}
private static void loadServlet() {
try {
//擷取web.xml目錄位址
String path = DiyTomcat.class.getResource("/").getPath();
SAXReader reader = new SAXReader();
//讀取web.xml檔案
Document document = reader.read(new File(path + "web.xml"));
//擷取根标簽(servlet和servlet-mapping),放在一個List中
Element rootElement = document.getRootElement();
List<Element> elements = rootElement.elements();
//循環将映射寫進map映射裡
for(Element element : elements){
if ("servlet".equalsIgnoreCase(element.getName())){
Element servletName = element.element("servlet-name");
Element servletClass = element.element("servlet-class");
//需要注意的是servletMapping映射的第二個參數,要通過反射的方式進行執行個體化
SERVLET_MAPPING.put(servletName.getText(),
(DiyServlet) Class.forName(servletClass.getText().trim()).newInstance());
}else if ("servlet-mapping".equalsIgnoreCase(element.getName())){
Element servletName = element.element("servlet-name");
Element urlPattern = element.element("url-pattern");
URL_MAPPING.put(urlPattern.getText(), servletName.getText());
}
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept();
RequestHandler requestHandler = new RequestHandler(socket);
// 一個 socket 一個線程
// new Thread(requestHandler).start();
// 使用線程組幹活
threadPoolExecutor.execute(requestHandler);
}
}
}
- 通過
方法建立出一個線程池initExecutors
private static void initExecutors() {
// 核心線程數
int corePoolSize = 10;
// 最大線程數
int maximumPoolSize = 50;
// 空閑線程保活時間
long keepAliveTime = 100L;
// 保活機關,目前設定為秒
TimeUnit unit = TimeUnit.SECONDS;
// 線程池隊列
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
// 線程建立工廠
ThreadFactory threadFactory = Executors.defaultThreadFactory();
// 池子滿後的拒絕請求處理器
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
threadPoolExecutor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory,
handler
);
}
-
到socket後直接包裝成accept
交由線程池處理RequestHandler
while (true) {
Socket socket = serverSocket.accept();
RequestHandler requestHandler = new RequestHandler(socket);
// 一個 socket 一個線程
// new Thread(requestHandler).start();
// 使用線程組幹活
threadPoolExecutor.execute(requestHandler);
}