关于servlet的多线程环境的问题

时间:2011-06-02 06:41:51

标签: java multithreading servlets

如果有一个servlet,则在诸如Websphere之类的servlet容器中。 servlet由一些线程执行。我想问一下,线程分享了什么?如何在它们之间共享变量?

他们是否拥有以下变量的本地副本?

1)私人/受保护/公共最终信号量许可=新信号量(50);

2)private / protected / public final static Semaphore permit = new Semaphore(50);

3)private / protected / public Semaphore permit = new Semaphore(50);

4)private / protected / public static Semaphore permit = new Semaphore(50);

我应该如何声明信号量以便我可以使用信号量来控制它们?我不希望他们每个人都拥有信号量的副本。感谢。

7 个答案:

答案 0 :(得分:2)

线程由Websphere线程池运行,您不应该担心访问它们或通过它们共享信息。

如果您在servlet中声明它是静态的,那么您的信号量将被共享,只要所有使用它的类都存在于同一个类加载器下的同一个应用程序中。但是,在这种情况下存在很大的风险,如果您的执行路径没有释放许可(例如由于异常),您可能最终阻止所有线程。

答案 1 :(得分:2)

每个线程都有自己的堆栈,但它们共享相同的内存空间。考虑到这一点,可以在多个线程之间共享单个实例,以及它的状态/属性。因此,我们需要使用同步或类似技术来处理状态。

如果定义一个静态变量或者将使用单个servlet实例 - 这很可能但不能保证,那么对于所有线程它都是相同的。

尽管如此,您应该创建一个类,该类提供要在servlet中使用的单例信号量。这样,servlet实例将使用同一个信号量对象,无论如何。

答案 2 :(得分:0)

如果你想共享一个信号量,它必须由一个线程创建,然后在需要时分发给其他人(通过某种形式的(可能是静态的)getter方法)。

如果你在每个对象中创建信号量对象,它们都会有不同的对象,从而无法实现目的。

答案 3 :(得分:0)

Servlet必须是线程安全的。这意味着你的servlet应该是“无状态的”(除非你真的知道你正在做什么)。基本上,只使用局部变量 - 而不是字段。

如果要共享状态,请务必使用servlet的字段,或使用具有静态字段和静态getter的类(如 singleton 模式)

答案 4 :(得分:0)

Servlet应该是线程安全的。意思是如果他们有任何状态,他们应该同步。尽量避免在servlet中保存一些状态。它们应该只包含业务/控制器逻辑。您要保存的任何状态,将它们放在由容器同步的servletcontext / request / session中。

答案 5 :(得分:0)

每个servlet都在一个新线程中执行。从技术上讲,有一个工作线程等待请求,当一个http请求进入servlet容器时,这个实例化一个新的servlet(取决于web.xml中定义的servlet)和将它传递给工作线程。因此逻辑上其他servlet实例看不到每个变量。现在,如果要使所有servlet实例都可以看到变量,则必须将其定义为静态,以便在同一个类的所有实例之间共享。

答案 6 :(得分:0)

即使在同一个JVM中,也不应指望servlet的两个实例。可以复制容器,并且您的Servlet需要无状态。除了Java EE规范之外,您不允许在其中执行任何线程操作。容器可以允许它,但行为然后变得特定于实现。通过在其中放置信号量,您干扰了池并可能导致问题。如果您需要区分不同的用户,请使用“会话”。