0

我有一个问题单例模式和线程。实现是这样的。

public class Singleton {
    private static final Singleton instance = new Singleton();

    private SomeClass someField;
    // and  another private fields

    private Singleton() {
        someField = new SomeClass(some args);
        // init another private fields
    }

    public Singleton getInstance() {
        return instance;
    }

    public void operation() {
        //some operations
        someField.method();
    }
}

(对不起,我不能提供真实的例子。)接下来的问题是:方法 operation() 线程安全吗?

4

3 回答 3

5

我们不知道它是否安全——我们不知道什么是安全的someField.method()

我强烈建议您创建someField一个final字段,就好像单例需要改变状态一样,如果没有额外的同步,它绝对不是线程安全的。如果SomeClass它本身是不可变的并且是线程安全的,那么你不应该需要任何其他同步 - 但否则,你会的。

基本上,单例没有什么“神奇的线程安全”。它只是一个实例,多个线程可以通过静态getInstance()方法访问它。如果该类是线程安全的,那么无论它是否是单例,它都是线程安全的——如果它不是线程安全的,那么将其设为单例将无济于事。

于 2012-09-08T14:47:21.467 回答
3

的线程安全someField.method();取决于它实际在做什么。如果它正在修改在多个线程之间共享的状态,那么它不是线程安全的。如果不是,它可能是线程安全的。但通常不应假定它是线程安全的。没有代码我不能说更多。

于 2012-09-08T14:47:57.533 回答
0

正如上面回答的那样,答案不是线程安全的。这可以作为下面的代码进行测试!


public class TestSingleton {
public static void main(String[] args) throws Exception {
    ExecutorService pool = Executors.newFixedThreadPool(10);
    for (int j = 0; j < 100000; j++) {
        pool.submit(new Thread() {
            public void run() {

                Singleton.get().add();
            }
        });
    }
    pool.shutdownNow();
    System.out.println(Singleton.get().getcnt());
}

}

class Singleton {
private static Singleton singleton = new Singleton();

int cnt = 0;

private Singleton() {}

public static Singleton get() {
    return singleton;
}

public void add() {
    cnt++;
}

public int getcnt() {
    return cnt;
}

}

于 2015-04-30T03:45:56.050 回答