辛格尔顿与初始化静态成员(Singleton with initializing a static

2019-10-29 07:15发布

在我最初设计它下面的代码片段中,“下一个号码”需要在整个应用程序的执行发送下一个递增的值。 所以,我提出了一个类单。 然而,随着需求最近的一些变化,我需要做的“未来号”复位。 我只是增加了一个复位的方法来做到这一点。 但是,它肯定违反了Singleton模式,也是我知道这不是初始化静态成员这样一个好主意。

你觉得我应该怎么办呢?

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();
    }
}

Answer 1:

为什么不是仅仅领域的实例变量? 世界上没有需要静态这里。

重置不需要进行任何同步,除非getNextNumber是也。



Answer 2:

看起来不错,我 - 除了两件事情:

  • getNextNumbersynchronized
  • 因为getNextNumberreset不是staticnextNumber并不需要是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);
    }
}

有关此futher讨论,参见例如在原子类在Java 5中:的AtomicInteger和AtomicLong的 :

Java 5中之前,我们不得不写个教学班,访问计数器变量的synchronized块或方法,或者使用volatile变量,它是同步的,但有,如果他们同时发生一些更新可能被遗漏的风险较轻的形式。 一个AtomicInteger可以作为一个简易替换,提供了两全其美...



文章来源: Singleton with initializing a static member