1

如果我声明一个像这样的单例 servlet

公共静态类 SomeServlet 扩展 HttpServlet {.....

它给出的错误指示在 NetBeans 中不允许使用修饰符 static。

请让我知道如何创建一个单例 servlet,它一次只允许一个客户端执行。

提前致谢, 马赫斯

4

5 回答 5

6
  • static与在任何时间点仅由一个线程执行无关。
  • 您可以将静态类作为内部类,但这对您的问题没有帮助,因为第一点
  • 如果我没记错的话,只有一个 servlet 实例化过,所以没有必要创建单例。更新:我没记错,正如 DefLog 指出的那样
  • 因此在方法(doGet、doPost、服务或您的实现方法)上同步更新:不会成功。

根据您对问题的理解(没有双关语),我怀疑这是您应该选择的解决方案。而是改写您的问题,以便用您在问题的第一次修订中陈述的解决方案陈述您要解决的问题。

更新:请参阅此答案的评论,了解为什么您真的不想爱上synchronized。您可能(例如)希望多个 servlet一次访问一个相同的功能。另外,如果您在 servlet 级别上进行同步,您会引入严重的扩展问题。这绝对是解决并发问题的错误地方。

于 2009-02-22T11:58:59.280 回答
3

我真的强烈反对制作一个一次只能处理一个请求的 Servlet。您可能应该创建另一个(正确同步的类)并让您的 servlet 将请求放入某种执行队列中。

于 2009-02-22T12:11:27.490 回答
1

实施SingleThreadModel。但请注意:它已被弃用,它可能没有任何作用/没有意义,这是一件愚蠢的事情(很像单身人士)。

于 2009-02-22T12:11:17.987 回答
0

顶级声明永远不可能是static. static意味着一个元素是在类级别声明的,所以它需要一个封闭的类声明。

对于 servlet,通常会有一个但可能有多个同时处理请求的 servlet 实例。所以,也许你真的不想在这个级别减少并发,或者你会使用 servlet 过滤器或像 Spring Security 这样可以限制并发会话数量的框架。

于 2009-02-22T12:37:11.453 回答
-3

我倾向于认为 Singleton 被过度使用,并且通常表明解决方案的基本架构存在缺陷。假设您已经完成了足够的分析以证明您需要一个单例,您可以使用不依赖静态初始化的旧单例模式。这是一个例子:

public SomeServlet extends HttpServlet {

    private instance = null;

    private SomeServlet() {
        // Construction code here
    }

    public synchronized SomeServlet getInstance() {
        if(instance == null) {
            instance = SomeServlet();
        }
        return instance;
    }

    // Servlet methods here

}

我看到两个潜在的问题:

首先,您需要一个包装器 Servlet(或者可能只是从另一个 servlet 链接,因为 Servlet 容器不知道如何处理没有私有构造函数的情况。

其次,您仍然需要同步 servlet 方法,因为您仍然不能保证一次只有一个执行程序线程“在”servlet 中。

于 2009-02-22T12:38:19.810 回答