我只是从 servlet 和线程开始。最终实例变量是线程安全的,CopyOnArrayList 也是如此。为什么以下代码不是线程安全的(它是最终的 + 我使用了 CopyOnArrayList)?
@WebServlet("/index.html")
public class CatServlet extends HttpServlet {
private final static long serialVersionUID = 1L;
private final static String VIEW = "/WEB-INF/JSP/index.jsp";
**private final CopyOnWriteArrayList <Cat> l = new CopyOnWriteArrayList<>();**
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
l.add(new Cat("Dean", 7));
l.add(new Cat("Sam", 7));
l.add(new Cat("Pixie", 0));
request.setAttribute("catList", l);
request.getRequestDispatcher(VIEW).forward(request, response);
}
JSP代码:
<c:forEach var="cat" items="${catList}" >
<li>${cat.name}</li>
</c:forEach>
首先我得到 3 个 Cat 实例。刷新时我得到 6,然后是 9、12,等等。为什么?当我在 doGet 方法中声明 CopyOnWriteArrayList 或使用简单数组时,不会出现此问题。我不明白它背后的逻辑:最终实例变量和 CopyOnWriteArrayList 应该是线程安全的。谢谢大家澄清这一点。