【问题标题】:Singleton methods thread safe单例方法线程安全
【发布时间】:2012-09-08 14:44:21
【问题描述】:

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

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() 线程安全吗?

【问题讨论】:

    标签: java multithreading design-patterns singleton


    【解决方案1】:

    我们不知道它是否安全 - 我们不知道 someField.method() 做了什么。

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        上面回答的答案不是线程安全的。 这可以通过下面的代码进行测试!


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

        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多