单例模式

来源:互联网 发布:淘宝买枪搜什么 编辑:程序博客网 时间:2024/06/02 02:24
     其实很早之前就明白了单例,但是因为在大学的时候课程设计都用不到单例,所以仅仅是知道单例,并没有仔细地思考过它的用途。今天是16年11月30号,今天因为项目需要需要写一个单例。在自己需要用单例的时候,为了程序的性能,自然要选择最优的单例。下面就各种单例说一说它们的优缺点。  1 懒汉模式
public class Singleton{              private static Singleton instance;              private Singleton(){}              public static Singleton getInstance(){              if(instance==null){              instance =  new Singleton();               }             return instance;               }    }
 这种方式的缺点很明显,就是线程不安全,当同时访问这个单例时,在创建单例的期间有人访问这个单例就又会创造一个实例,造成错误。

2 懒汉模式改进版

public class Singleton{            private static Singleton instance;            private Singleton(){}            public static synchronized Singleton getInstance(){            if(instance==null){           instance = new Singleton();           }           return instance;           }  }
这种方式线程上虽然安全,但是因为实际只有很小一部分情况需要用到锁,加锁降低了效率。所以这个方法也是不好的,线程虽然安全了,但是效率很低。

3 恶汉模式

 public class Singleton{          private static Singleton instance = new Singleton();          private Singleton(){}         public static Singleton getInstance(){         return instance;         }  }
  这种方式的优缺点也很明显,优点是线程安全的,但是却浪费空间。在不使用这个类的时候就实例化了这个类。当然有很多情况这个方式是不错的,比如随着程序的启动就 要实例化的单例。今天就碰到了这种需求,但是我还是选择了最优的单例方式。

4 双重检测模式

public class Singleton{        private static Singleton instance;        private Singleton(){}        public static Singleton getInstance(){       if(instance==null){       synchronized(Singleton.class){      if(instance==null){      instance = new Singleton()      }      }      }    return instance;       } }

这里说一下为什么要双重检测,因为第一次判断为空的时候,在给.class文件加锁之前可能这个类已经被实例化了,所以需要再判断一次。这里说一下如果对方法加锁是线程
安全的,但是效率不好,因为一时间只有一个线程可以调用这个方法。现在是给.class文件加锁,也就是说如果这个类已经实例化了,就可以直接调用了,唯一产生竞争的瞬间就是在实例化第一次的时候。

原创粉丝点击