概念:**单例模式指的是不管你去创建多少次对象,对象始终都只有一个。**

这里主要介绍了四种方式

懒汉式:只在第一次调用的时候创建,之后不再创建。

  1. public class SingletonLazy {
  2. private static SingletonLazy singletonLazy = null ;
  3. private String objName ;
  4. private SingletonLazy(){
  5. }
  6. public static SingletonLazy getSingletonLazy(){
  7. //此处线程不安全
  8. if (singletonLazy == null ){
  9. singletonLazy = new SingletonLazy();
  10. }
  11. return singletonLazy;
  12. }
  13. public String getObjName() {
  14. return objName;
  15. }
  16. public void setObjName(String objName) {
  17. this.objName = objName;
  18. }
  19. }

以上代码在标记线程不安全处会发生线程安全问题:
场景线程1第一次来到标记处,此时singletonLazy 还是为null,所以马上要创建对象,但此时刚好分配的时间片用完,还未执行创建对象。此时线程2进入,应为此时singletonLazy还未创建,所以还是null,所以线程2能去创建对象。线程2创建完对象,然后这时线程1又开始执行了,此时会接着上次执行的代码处执行,即创建一个新的对象,此时就会创建出两个不一样的对象。

饿汉式

在类加载的时候就已经创建了,所以是线程安全的,但是就是消耗资源多。在不需要的时候也存在该对象。

  1. public class SingletonHunger {
  2. private static SingletonHunger singletonHunger = new SingletonHunger();
  3. private SingletonHunger(){}
  4. public static SingletonHunger getSingletonHunger(){
  5. return singletonHunger;
  6. }
  7. }


静态内部类

其实就是在饿汉式的基础上的改进,因为饿汉式会在类加载的时候就创建对象,所以会消耗不必要的内存。所以我们引进内部类来创建对象,因为内部类的静态变量并不会随着外部类加载而创建。同时这个是一个线程安全的创建方式。

  1. public class SingletStaticClass {
  2. SingletStaticClass(){}
  3. private static class InnerClass{
  4. //内部类加载的时候创建
  5. static final SingletStaticClass singletStaticClass = new SingletStaticClass();
  6. }
  7. public static SingletStaticClass getSingletStaticClass(){
  8. return SingletStaticClass.InnerClass.singletStaticClass;
  9. }
  10. }

双检查加锁

是懒汉式改进,因为懒汉式是一个线程不安全的单例模式,所以这里引进锁的方式。其实可以直接写一个同步方法的,但是这样性能太差了,不考虑。因此就在方法内加上锁,但是要又双重判断,不然也是会线程不安全的。

  1. public class SingletDoubleLok {
  2. private static volatile SingletDoubleLok singleton;
  3. private SingletDoubleLok(){}
  4. public static SingletDoubleLok getSingletDoubleLok(){
  5. if (null == singleton){
  6. synchronized (singleton){
  7. if (null == singleton){
  8. singleton = new SingletDoubleLok();
  9. }
  10. }
  11. }
  12. return singleton;
  13. }
  14. }