【问题标题】:Singleton with initializing a static member初始化静态成员的单例
【发布时间】:2010-11-07 00:02:17
【问题描述】:

在下面我最初设计的代码 sn-p 中,“下一个数字”需要在整个应用程序执行过程中发送下一个递增值。所以我把这个班级变成了单身人士。但是,随着最近要求的一些变化,我需要对“下一个数字”进行重置。我刚刚添加了一个重置​​方法来做到这一点。但是,它肯定违反了单例模式,而且我知道以这种方式初始化静态成员不是一个好主意。

你觉得我应该怎么做?

public final class GetNextNumber {
    private static GetNextNumber instance; 
    private static Integer nextNumber=1;
    private GetNextNumber() {
    }
    public static synchronized GetNextNumber getInstance() {
        if(instance==null){
            instance = new GetNextNumber();
        }
        return instance;
    } 
    protected Integer getNextNumber(){
        return nextNumber++;
    }
    protected synchronized void reset(){
        nextNumber=1;
    }
    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}

【问题讨论】:

  • 你不需要那个 clone() 方法。它所做的只是重现默认行为。由于您的课程是最终的并且没有实现 Cloneable ,因此无论如何它都没有任何其他行为。它还使 clone() 公开而不是受保护,在这种情况下是徒劳的。

标签: java static singleton


【解决方案1】:

为什么字段不只是实例变量?这里不需要静态。

reset 也不需要同步,除非 getNextNumber 也一样。

【讨论】:

    【解决方案2】:

    在我看来还可以——除了两件事:

    • getNextNumber 不是 synchronized
    • 因为getNextNumberreset 不是static,所以nextNumber 也不需要是static

    您可以使用AtomicInteger 来避免使您的getNextNumberreset 方法synchronized

    public final class GetNextNumber {
    
        private static GetNextNumber instance;
    
        private AtomicInteger nextNumber = new AtomicInteger(1);
    
        private GetNextNumber() {
        }
    
        public static synchronized GetNextNumber getInstance() {
            if(instance==null){
                instance = new GetNextNumber();
            }
            return instance;
        } 
    
        protected Integer getNextNumber(){
            return nextNumber.getAndIncrement();
        }
    
        protected void reset(){
            nextNumber.set(1);
        }
    }
    

    有关此问题的进一步讨论,请参阅例如The Atomic classes in Java 5: AtomicInteger and AtomicLong

    在 Java 5 之前,我们必须编写类 可以访问计数器变量 synchronized 块或方法,或 否则使用 volatile 变量,它是 一种较轻的同步形式,但 有一些更新可能 如果它们同时发生,将被错过。 AtomicInteger 可以用作 即插即用的替代品,提供 两全其美...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      • 1970-01-01
      • 2015-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多