Singleton初始化静态成员

时间:2010-11-07 00:02:18

标签: java static singleton

在我最初设计它时的下面的代码片段中,在整个应用程序执行期间发送下一个递增值所需的“下一个数字”。所以我让这个班成了一个单身人士。但是,随着最近的一些要求变化,我需要对“下一个号码”进行重置。我刚刚添加了一个重置​​方法来做到这一点。但是,它肯定违反了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();
    }
}

2 个答案:

答案 0 :(得分:2)

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

reset也不需要同步,除非getNextNumber也是如此。

答案 1 :(得分:2)

对我来说没问题 - 除了两件事:

  • getNextNumber不是synchronized
  • 由于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);
    }
}

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

  

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