程序员面试题----单例模式

Posted 程序猿的搞笑生活

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序员面试题----单例模式相关的知识,希望对你有一定的参考价值。

程序员面试题----单例模式

 

单例模式:一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例

单例模式有一下特点:
  1、单例类只能有一个实例。
        2、单例类必须自己自己创建自己的唯一实例。
        3、单例类必须给所有其他对象提供这一实例。

单例模式的3种形式

(1)     懒汉式单例:单例实例在类装载时就构建,急切初始化。(预先加载法) 

1.  public class Singleton {  

2.      private Singleton() {}  

3.      private static Singleton single=null;  

4.      //静态工厂方法   

5.      public static Singleton getInstance() {  

6.           if (single == null) {    

7.               single = new Singleton();  

8.           }    

9.          return single;  

10.     }  

11. }  

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全

1、在getInstance方法上加同步

1.  public static synchronized Singleton getInstance() {  

2.           if (single == null) {    

3.               single = new Singleton();  

4.           }    

5.          return single;  

6.  }  

2、双重检查锁定

1.  public static Singleton getInstance() {  

2.          if (singleton == null) {    

3.              synchronized (Singleton.class) {    

4.                 if (singleton == null) {    

5.                    singleton = new Singleton();   

6.                 }    

7.              }    

8.          }    

9.          return singleton;   

10.    }  

3.静态内部类

    public class Singleton {    

  private static class LazyHolder {    

1.         private static final Singleton INSTANCE = new Singleton();    

2.      }    

3.      private Singleton (){}    

4.      public static final Singleton getInstance() {    

5.         return LazyHolder.INSTANCE;    

6.      }    

7.  }    

 


2)饿汉式单例:单例实例在第一次被使用时构建,延迟初始化。 

1.  //饿汉式单例类.在类初始化时,已经自行实例化   

2.  public class Singleton1 {  

3.      private Singleton1() {}  

4.      private static final Singleton1 single = new Singleton1();  

5.      //静态工厂方法   

6.      public static Singleton1 getInstance() {  

7.          return single;  

8.      }  

9.  }  

优点: 
    避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。 
缺点: 
    懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。 

3)登记式单例。

登记式实际对一组单例模式进行的维护,主要是在数量上的扩展,通过map我们把单例存进去,这样在调用时,先判断该单例是否已经创建,是的话直接返回,不是的话创建一个登记到map中,再返回。对于数量又分为固定数量和不固定数量的。下面采用的是不固定数量的方式,在getInstance方法中加上参数(string name)。然后通过子类继承,重写这个方法将name传进去。代码:

10. public class Singleton3 {  

11.     private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();  

12.     static{  

13.         Singleton3 single = new Singleton3();  

14.         map.put(single.getClass().getName(), single);  

15.     }  

16.     //保护的默认构造子  

17.     protected Singleton3(){}  

18.     //静态工厂方法,返还此类惟一的实例  

19.     public static Singleton3 getInstance(String name) {  

20.         if(name == null) {  

21.             name = Singleton3.class.getName();  

22.             System.out.println("name == null"+"--->name="+name);  

23.         }  

24.         if(map.get(name) == null) {  

25.             try {  

26.                 map.put(name, (Singleton3) Class.forName(name).newInstance());  

27.             } catch (InstantiationException e) {  

28.                 e.printStackTrace();  

29.             } catch (IllegalAccessException e) {  

30.                 e.printStackTrace();  

31.             } catch (ClassNotFoundException e) {  

32.                 e.printStackTrace();  

33.             }  

34.         }  

35.         return map.get(name);  

36.     }  

37.     //一个示意性的商业方法  

38.     public String about() {      

39.         return "Hello, I am RegSingleton.";      

40.     }      

41.     public static void main(String[] args) {  

42.         Singleton3 single3 = Singleton3.getInstance(null);  

43.         System.out.println(single3.about());  

44.     }  

45. }  

 

图片人物来自《魔女宅急便》

 


以上是关于程序员面试题----单例模式的主要内容,如果未能解决你的问题,请参考以下文章

面试阿里,字节跳动,腾讯90%会被问到的面试题—— 单例模式

JAVA就业面试题之单例模式

单例模式,这个面试题真那么简单吗?

JavaSE面试题:单例设计模式

JavaSE面试题之单例模式

面试题复习-常用设计模式-单例设计模式