javamultithreadingjspservletscopyonwritearraylist

Thread safety with CopyOnArrayList in servlet


I'm just starting with servlets & threading. Final instance variables are thread-safe and so is CopyOnArrayList. Why is the following code NOT thread-safe (it's final + I used 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 code:

<c:forEach var="cat" items="${catList}" >
    <li>${cat.name}</li>
</c:forEach>

First I get 3 Cat instances. When refreshing I get 6, then 9, 12, etc. Why? The problem does not occur when I declare the CopyOnWriteArrayList within the doGet method, nor when I do it with a simple array. I do not understand the logic behind it: a final instance variable and CopyOnWriteArrayList should be thread-safe. Thank you all for clarifying this.


Solution

  • You are adding 3 elements in your list each time you refresh the page since you add them in your doGet method.

    If you declare your list in your doGet method, it will be erased each time the method is called.

    There is no thread safety involved here.