读书人

线程保险的单例类

发布时间: 2012-12-28 10:29:05 作者: rapoo

线程安全的单例类
单例模式中,有两种实现,一种是饥饿模式,另一种是懒汉模式。
饥饿模式的实现:

public final class EagerSingleton  {      private static EagerSingleton instance = new EagerSingleton();                private EagerSingleton(){      }        public static EagerSingleton getSingleInstance(){          return instance;    }  }  

优点:线程安全
缺点:未使用该对象的时候,已经加载到了内存,但对象很大的时候是一种浪费

懒汉模式的基本实现:
public final class LazySingleton {      private static LazySingleton instance = null;        private LazySingleton(){      }        public static LazySingleton getSingleInstance(){          if(null == instance ) {    instance = new LazySingleton();}eturn instance;    }  }  

优点:延迟加载,按需分配内存
缺点:线程不安全,如果两个线程同时第一次访问getInstance方法,则会生成两份实例。

为了解决懒汉模式的线程安全问题,第一种解决方法是在getInstance方法前加入synchronized修饰。
public final class LazySingleton {      private static LazySingleton instance = null;        private LazySingleton(){      }        public static synchronized LazySingleton getSingleInstance(){          if(null == instance ) {    instance = new LazySingleton();}eturn instance;    }  }  


第一种方法可以解决线程安全问题,但使用synchronized同步必将降低性能,所以可以考虑将同步的粒度降低,所以有了第二种解决方法。
public final class DoubleCheckedSingleton {      private static DoubleCheckedSingleton instance = null;        private DoubleCheckedSingleton(){      }        public static DoubleCheckedSingleton getSingleInstance(){          if(instance == null ) {            Synchronized(DoubleCheckedSingleton.class){                if(instance == null){            instance = new DoubleCheckedSingleton();                }    }}return instance;    }  }  

第二种解决方法,实现了线程安全,同时也将同步的粒度降低到代码块中,提高了性能。但第二种解决方法是用双重检查锁来实现,这种做法是不推荐使用的。
那么就有了第三种解决方法,使用内部类来延迟加载,在类的加载过程中会保证线程的安全。
public class Singleton {        private static class SingletonHolder {            public final static Singleton instance = new Singleton();        }           public static Singleton getInstance() {            return SingletonHolder.instance;        }    }  

读书人网 >编程

热点推荐