设计模式笔记——单例模式

单例模式,又叫单态模式或者单件模式。

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例通常用来代表那些本质上具有唯一性的系统组件(资源)。

目的:控制特定的类只产生一个对象。

单例模式可以分为有状态和无状态的。有状态的单例对象一般也是可变的单例对象,多个单例对象在一起可以作为一个状态仓库向外提供服务。没有状态的对象就是不变的单例对象,仅仅作用提供工具函数。

饿汉式:先new 出来实例,再返回。

 1 public class Singleton {
 2 
 3   private static Singleton instance = new Singleton();
 4 
 5   private Singleton () {
 6   }
 7 
 8   public static Singleton getInstance() {
 9     return instance;  
10   }
11 
12 }

懒汉式:调用的时候再new出实例。  使用synchronized 防止多线程环境产生多个实例,饿汉式不存在这种情况。

 

 1 public class Singleton {
 2     private static Singleton instance = null;
 3 
 4     private Singleton() {
 5     }
 6     
 7     public static synchronized Singleton getInstance() {
 8         if (instance == null) {
 9             instance = new Singleton();
10         }  
11         
12         return instance;
13     }        
14 }

以上两种实现方式均失去了多态性,不允许被继承。

带有注册表的方式

带有注册表的实现(HashMap):

 1 import java.util.HashMap;
 2 
 3 public class Singleton 
 4 {
 5     private static HashMap sinRegistry = new HashMap();
 6 
 7     static Singleton() {}
 8 
 9     public static Singleton getInstance(String name) {
10         if (name == null) {
11             name = "Singleton";
12         }
13 
14         if (sinRegistry.get(name) == null) {
15             try {
16                 sinRegistry.put(name, Class.forName(name).newInstance());
17             } catch (Exception e) {
18                 e.printStackTrace();
19             }
20         }
21 
22         return (Singleton) (sinRegistry.get(name));
23     }
24     
25     public void test () {
26         System.out.println("getclasssucess!");
27     }      
28 }
29 
30 public class SingletonChild1 extends Singleton 
31 {
32     public SingletonChild1() {}
33 
34     public  static SingletonChild1 getInstance() {
35         return (SingletonChild1) Singleton.getInstance("SingletonChild1");
36     }
37 
38     public void test() {
39         System.out.prinln("getclasssuccess111!");
40     }
41 }

单例模式在Java中的陷阱:

1. 多个虚拟机,或者分布式系统中,当系统单例类被拷贝运行在多个虚拟机下的时候,每一个虚拟机下都可以创建一个实例对象。因此在使用分布系统时,应该避免使用单利模式。

2.多个类加载器,当存在多个类加载器的时候,因为不同的类加载器会使用不同的namespace来区分同一个类,因此,单例类在多加载器环境下会产生多个单例对象。

3.错误的同步处理,使用懒汉模式时候要对同步有所了解,否则会引发死锁错误或者得不到单例效果。饿汉模式不存在该问题。

4.子类破坏了对象控制

5.串行化。一个串行化的对象在每次返回串行化的时候都会创建新的对象,而不仅仅是一个对原有对象的引用。为防止这种情况,除了在生命中添加implements Serializable, 还可以在单例中加入readResolve方法。

永远单例:  public static final Singleton INSTANCE = new Singleton();

原文地址:https://www.cnblogs.com/JacobQiao/p/4758823.html