单例模式:确保一个类只有一个实例,并提供一个全局访问点。
单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。例如每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态。
优点:
一、实例控制
单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
二、灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
缺点:
一、开销
虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
二、可能的开发混淆
使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
显然单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 从具体实现角度来说,就是以下三点:一是单例模式的类只提供私有的构造函数,二是类定义中含有一个该类的静态私有对象,三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
——————————————————————————————————————————
懒汉式单例:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//懒汉式单例类.在第一次调用的时候实例化自己,延迟加载
public class Singleton {
private Singleton() {}
//静态私有对象,保证该类只有一个实例
private static Singleton single=null;
//静态工厂方法
public static Singleton getInstance() {
if (Singleton.single == null) {
single = new Singleton();
}
return single;
}
}
|
以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全.
2、双重检查锁定
1
2
3
4
5
6
7
8
9
10
|
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
|
当然,如果getInstance()的程序用在频繁运行的地方,就要重新考虑了,毕竟,同步一个方法会使运行效率急速下降,这时要考虑使用,饿汉式单例模式。
饿汉式单例:
1
2
3
4
5
6
7
8
9
|
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
|
JVM在加载这个类时,马上创建此唯一的单件实例。JVM保证在任何线程访问uniqueInstance静态变量之前,一定先创建此实例。所以说饿汉式单例模式是天生安全的。当然这样就丧失了延迟加载的优点。