关于#java#的问题:如果threadlocal 每次拿到的对象都不一样那threadlocal 在web中不是没有意义吗

tomcat 与 threadlocal 中的Executor was closed.

使用tomcat服务器的一段座位预定代码,getSeatFromDB(seatId)这个方法每次都是第五次执行的时候就报错Executor was closed,发现好像还是threadlocal 的问题,本意是让他每次都能拿到同一个对象,但是发现结果是每次都会创建一个新的线程对象,所以每次拿到的对象都不一样。不知道如何修改,如果threadlocal 每次拿到的对象都不一样那threadlocal 在web中不是没有意义吗?

public class ReserveServlet02 extends HttpServlet {
    
    private final Lock lock = new ReentrantLock();


    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        int seatId = Integer.parseInt(request.getParameter("seatId"));

        Seat seat = getSeatFromDB(seatId);

        if (seat.getStatus() == 1) {
            if (reserveSeat(seat)) {
                response.sendRedirect(request.getContextPath() + "/reserveSuccess.jsp");
            } else {
                response.sendRedirect(request.getContextPath() + "/reserveFail.jsp");
            }
        } else {
            response.sendRedirect(request.getContextPath() + "/reserveFail.jsp");
        }
    }


    public boolean reserveSeat(Seat seat) {
        boolean isSuccess = false;


        if (seat != null && seat.getStatus() == 1) {
            seat.setStatus(2);

            SqlSession sqlSession2 = DBUtil2.openSession();//添加事务
            SeatMapper seatDAO = sqlSession2.getMapper(SeatMapper.class);
            isSuccess = seatDAO.updateSeat(seat);
            sqlSession2.commit();
            sqlSession2.close();
        }

        return isSuccess;
    }

    public Seat getSeatFromDB(int seatId) {
        Seat seat = null;
        try (SqlSession sqlSession = DBUtil2.openSession()) {
            SeatMapper seatDAO = sqlSession.getMapper(SeatMapper.class);
            seat = seatDAO.getSeatById(seatId);
            System.out.println("---------------");
            System.out.println("Thread" + Thread.currentThread());
            System.out.println("sqlSession:" + sqlSession);
            System.out.println("seatDAO"+ seatDAO);
            System.out.println("---------------");
        }catch (Exception e) {
            e.printStackTrace();
        }
        return seat;
    }

}

ThreadLocal 是一种线程封闭技术,它可以让每个线程拥有自己独立的变量副本,不同线程之间的变量相互独立。在多线程环境下,使用 ThreadLocal 可以有效地避免线程安全问题,提高程序的并发性能。

在 Web 应用程序中,每个请求通常会被分配到不同的线程上处理。使用 ThreadLocal 可以让不同请求之间的变量相互独立,避免多个请求之间产生数据干扰,保证程序的正确性。因此,ThreadLocal 在 Web 应用程序中是有意义的。

每次通过 ThreadLocal.get() 方法获取到的对象都是该线程独立的对象副本。如果每次获取到的对象都不一样,可能是因为在获取对象之前没有初始化该对象或者每次获取对象都是新的实例。因此,应该在使用 ThreadLocal 时,确保在每个线程中都初始化了该对象,以保证获取到的对象是正确的。

另外,需要注意的是,使用 ThreadLocal 也需要注意内存泄漏的问题。由于 ThreadLocal 中的对象只能被对应的线程访问,如果该线程没有被正确地销毁,那么 ThreadLocal 中的对象也会一直存在,导致内存泄漏。因此,在使用 ThreadLocal 时,需要注意在合适的时候将对象清除或者使用弱引用等方式避免内存泄漏问题。

从你的代码中,并没有看到这个问题和ThreadLocal有什么关系呀。
另外,你的代码中 Lock lock = new ReentrantLock(); 创建了这个lock,但没有用啊?
至少你要调用 lock.lock();来进行锁定啊。