日期:2014-05-20  浏览次数:20775 次

Singleton 是线程安全的吗?
Singleton 的实例在内存中只有一个,那么它是线程安全的吗?

------解决方案--------------------
如果一个类适合做成单例的,那么写这个单例的人有必要保证这个类的线程安全性
------解决方案--------------------
这个不确定,单例只保证只能创建一个对象,不能保证线程安全。这个需要看单例中是否考虑了线程问题。如果没有可以加上。
------解决方案--------------------
Java code
public class Controller { 
private static Controller instance; 
private static Object lock = new Object(); 

private Controller() 
{ 
// do something 
} 

public final static Controller getInstance(){ 
if (instance != null) 
    return instance; 
synchronized (lock){ 
if (instance != null) 
    return instance; 
Controller tmp = new Controller(); 
instance = tmp; 
} 
return instance; 
} 

// some more methods 
}

------解决方案--------------------
路过,学习
------解决方案--------------------
探讨

如果一个类适合做成单例的,那么写这个单例的人有必要保证这个类的线程安全性

------解决方案--------------------
单例说明只有一个实例对象,但是多线程的操作,也还是有可能造成不一致的情况吧
------解决方案--------------------
这个不确定,单例只保证只能创建一个对象,不能保证线程安全。这个需要看单例中是否考虑了线程问题。如果没有可以加上
------解决方案--------------------
servlet运行时也只有一个实例,可线程的安全还是要由于发者在用的时候来控制.
Singleton 也同理.
------解决方案--------------------
看是谁写的了。。。
------解决方案--------------------
Java code

public class Tiger6 {
    static class Inner {
        private static Inner instance = null;

        private Inner() { // 每调用一次构造函数,打印一条消息。
            System.out.println("create a Inner object!");
        }

        public static Inner getInstance() {
            if (instance == null) {
                //主要问题是出现在这里的。当一个线程判断instance == null,然后时间片到期
                //另外一个线程进入判断为空,然后创建Inner()对象。当开始的线程运行时从这里
                //开始然后又创建了Inner()这样的话,就执行了两次,当然这种情况是不可控的,
                //有多少个线程每一次运行的时候是不确定的,所以就会出现多种情况。我们开的线程
                //越多,这种情况就越有可能出现。总之这里线程不是安全的,加上synchronized
                //关键字后,就可以解决这个问题了。
                
                //如果在下面加上Thread.sleep(10),那么create a Inner object!就会出现100次。
                //每一次都会出现上面的情况。
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                instance = new Inner();
            }
            return instance;
        }
    }

    public static void main(String[] args) {
        Thread[] ts = new Thread[100];
        for (int i = 0; i < ts.length; i++) {
            System.out.println(i);
            ts[i] = new Thread(new Runnable() {
                public void run() {
                    Inner.getInstance();
                }
            });
        }
        for (Thread t : ts) {
            
            t.start();
        }
    }
}