系列回顧篇:展示最原始、無同步、無持久化的計數器第一版,作為後續版本演進的基準,直觀展示併發Bug與重啟歸零問題。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>計數器第一版</title></head><body>
Hello World!
<%
// 直接從 application 域取得計數器
Integer count = (Integer) application.getAttribute("INDEX_COUNTER");
// 首次訪問初始化
if (count == null) {
count = 0;
application.setAttribute("INDEX_COUNTER", count);
}
count++; // 訪問次數 +1
application.setAttribute("INDEX_COUNTER", count); // 寫回
%>
當前總訪問次數:<%= count %>
</body></html>


| 問題 | 現象 | 原因 | 解決方向 |
|---|---|---|---|
| 併發安全 | 多用戶同時訪問,計數遺漏(如 100 並發僅增 60) | 「讀-改-寫」非原子,線程覆蓋彼此結果 | synchronized / AtomicInteger / 資料庫行鎖 |
| 資料持久化 | Tomcat 重啟/重新部署,計數歸零 | application 域隨 ServletContext 銷毀 | 檔案 / 資料庫 / Redis 持久化 |