当前位置: 代码迷 >> J2SE >> Singleton 是线程安全的吗?解决办法
  详细解决方案

Singleton 是线程安全的吗?解决办法

热度:549   发布时间:2016-04-24 12:33:00.0
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();        }    }}
  相关解决方案