Singleton的其他成员

时间:2013-08-08 19:42:48

标签: java tomcat web-applications executorservice threadpoolexecutor

我的问题很广泛,所以我分成两部分,并试图尽可能具体地说明我目前所知的事情。

第一部分

单身人士拥有自己的私人静态实例。关于单身人士的一些问题:
1。它的成员是否也应该是静态的,还是取决于要求?
2。如果对1.的答案明确是肯定的,那么如果所有成员都属于该类,那么开始使用私有实例变量的意义何在?
3。是否需要私有实例,因为JVM需要一个可重用的对象(单例)来保持其(JVM)生命的长度?

第二部分

需要在tomcat托管的Web应用程序中进行多个并发远程调用(该应用程序对某些组件使用GWT,因此如果一个好的解决方案需要,我可以使用servlet来满足上述要求)。目前,我创建了一个带有cached thread pool的执行程序服务,我将callables(每个可调用的包含端点配置)传递给该服务,用于需要此类调用的每个单独的流程。对我而言,如果线程池由多个流共享,而不是自己生成池,那将是有意义的。持有静态线程池的单例是一个很好的解决方案吗?

4 个答案:

答案 0 :(得分:1)

  1. Singleton的成员不必是静态的。
  2. 通过回答第1点而失效。
  3. 单身人士不需要私有的自身实例。如果单例上有任何其他非静态成员,则需要将实例存储到静态成员(公共或私有)。如果有任何非静态成员(这取决于您的要求),那么您需要一个实例来访问该成员(是的,如果成员是非静态的,JVM需要一个可参考的对象)

答案 1 :(得分:1)

需要注意的是,区分单例(一个只有一个实例的类/对象)的概念和通过一个类来实现这一点的设计模式很重要,该类通过一个类来保存自己的单个静态实例。全局静态名称空间。单例的概念经常在设计中使用,但是通过单例设计模式实现它往往是不受欢迎的。

在下面,单例用于指代特定的设计模式。

第1部分

  1. Singleton的成员不需要是静态的,通常不是。
  2. 见1.
  3. 单例(设计模式)需要一个实例,以便将该实例返回给单例的用户,并保持对自身的引用,以避免垃圾回收(如您所建议的那样)。没有这个单一实例,该对象基本上不是单例设计模式的实现。您可以创建一个只为其创建单个实例的类,并将该类传递到所需的位置(避免使用全局静态命名空间),这实际上是避免使用单例模式的推荐方法。
  4. 第2部分:

    共享你的线程池可能是明智的(但取决于你的要求),这可以通过多种方式完成。一种方法是创建单个池并将此池(注入它)传递到需要它的类中。通常建议使用像Spring这样的东西来处理这个问题。

    使用单例也是一种选择,但即使你的线程池封装在一个单例中,通常最好将这个单例(最好通过接口引用)注入依赖对象(通过setter或者它们的构造函数)而不是让你的对象静态地引用单例。这有多种原因,测试,灵活性和对实例化顺序的控制就是一些例子。

答案 2 :(得分:1)

  1. Singleton成员不需要是静态的
  2. 请看第1点
  3. Singleton实例必须是静态的(当然)并且必须通过静态方法访问;在成瘾中必须有一个私有构造函数来阻止创建新实例

  4. public class SingletonNumber10 {  
      public static SingletonNumber10 getInstance() {
        if(null == instance) {
          instance = new SingletonNumber10(10);
        }
        return instance;
      }
      private int number;
      private static SingletonNumber10 instance;
      private SingletonNumber10(int number) {
        this.number = number;
      }
      public int getNumber() {
        return this.number;
      }
      public static void main(String[] args) {
        System.out.println(SingletonNumber10.getInstance());
        System.out.println(SingletonNumber10.getInstance());
      }
    }
    

答案 3 :(得分:1)

A singleton holds a private static instance of itself. 

事实上,并非总是这不是用Java做的最佳方式。

public enum Director {

   INSTANCE;

   public int getFive() {
     return 5;
   }

}

是一个完全有效的单例,并且更有可能保留存在的唯一副本而不是拥有自身私有静态实例的类。

1. Should it's members also be static

不,成员不应该是静态的,因为那样就不需要一个类,因此不需要该类成为单例。所有静态例程都受代码维护问题的影响,类似于C / C ++函数。即使使用单例,您也不会有多个实例需要处理,将该方法从实例中移除可以为您提供某些将来变形代码的能力。

2. If the answer to 1. is unequivocally yes.

不是,所以不需要回答#2。

3. Is the private instance needed because the JVM needs a 
   referable object (THE singleton) to hold on to for the
   length of its (JVM's) life?

不,需要私有实例,因为您必须有能力确定是否在访问之前调用了构造函数。这通常通过检查实例变量是否为空来完成。考虑到竞争条件和类加载器的考虑,使这些代码正确是非常困难的。使用枚举技术,您可以确保仅存在实例,因为JVM内部不受相同类型的竞争条件的影响,即使它们是,也只保证一个实例呈现给程序环境。 / p>

There is a requirement to make multiple concurrent remote calls within
a tomcat hosted web application (the app utilizes GWT for some components,
so I can utilize a servlet for this aforementioned requirement if a good 
solution requires this). Currently, I create an executor service with a cached 
thread pool into which I pass my callables (each callable containing an endpoint
configuration), for each individual process flow that requires such calls. To 
me it would make sense if the thread pool was shared by multiple flows, instead
of spawning pools of their own. Would a singleton holding a static thread pool be
a good solution for this?

这取决于。池中的线程有什么用?如果它是处理任务的线程,最终它们将全部与长时间运行的任务捆绑在一起,可能会使其他关键处理工作匮乏。如果您要执行大量任务,那么重建类似于NIO中使用的回调模式的处理可能实际上可以提供更好的性能(一个线程处理多个任务的回调调度,没有池) 。

在您提出处理问题的第二种方法,或者提供有关可用操作环境的更多详细信息之前,所提出的唯一解决方案通常是一个很好的解决方案。

PS。请不要扩展环境的细节。问题提交过程很简单,因此如果您想扩展第二部分,请将其重新提交为独立问题。