例如,用户可能访问一个 servlet,而该 servlet 有一系列关于会话的操作,这可能需要一些时间。同时,用户打开另一个窗口并访问另一个有关会话的 servlet。由于这两个 servlet 由同一用户访问,因此它们使用相同的会话变量。所以我认为往往存在同步问题。
如果存在这样的问题,使用同步块是否足以解决问题?(我认为同步块只能处理同一个线程中的事情。)
例如,用户可能访问一个 servlet,而该 servlet 有一系列关于会话的操作,这可能需要一些时间。同时,用户打开另一个窗口并访问另一个有关会话的 servlet。由于这两个 servlet 由同一用户访问,因此它们使用相同的会话变量。所以我认为往往存在同步问题。
如果存在这样的问题,使用同步块是否足以解决问题?(我认为同步块只能处理同一个线程中的事情。)
会话本身是线程安全的。但这并不意味着在没有任何同步的情况下使用它会导致正确的行为。这仅意味着如果由多个线程访问,会话将正常运行。
例如,假设您同时执行以下代码:
Integer visitCount = (Integer) session.getAttribute("visitCount");
visitCount = Integer.valueOf(visitCount.intValue() + 1);
session.setAttribute("visitCount", visitCount);
并假设 的原始值为visitCount
0。最终结果可能是 2(预期值),也可能是 1。事实上,两个线程都可以同时读取当前值 (0),然后都将其递增到 1,并且两者都将其存储在会话中。
同样,如果您在会话中存储一个线程不安全的对象(例如 HashMap),并且两个线程同时使用此 HashMap,您可能会看到不稳定的行为。
与每个多线程程序一样,您必须在必要时使用适当的同步机制,和/或使您的对象成为线程安全的。但这是整本书的主题。我会在实践中推荐 Java Concurrency。