程序员面试题----单例模式
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. }
图片人物来自《魔女宅急便》
以上是关于程序员面试题----单例模式的主要内容,如果未能解决你的问题,请参考以下文章