一、概述书接上回,之前我我们讲到原型设计模式。这次我们谈谈单例模式。单例模式是最喜闻乐见的设计模了,因为是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。他保证只有一个实例而且提供给全局使用
二、类图:
三、实现
类图十分简单只要保证类能提供一个实例就可以,既然要保证只提供一个实例。那么要将构造方法设计为私有属性。就如Effective JAVA中的一种方式提供一个静态工厂方法返回对象实例即可。其实实现单例模式的有挺多种的,这让我想起《孔乙己》里面一句话“你知道茴豆的茴字有几种写法吗” 那么单例模式有多少中写法呢?答案是6种
1.懒汉模式(线程不安全 )
通过提供一个静态的对象instance,利用private权限的构造方法和getInstance()方法来给予访问者一个单例。缺点是,没有考虑到线程安全,可能存在多个访问者同时访问,并同时构造了多个对象的问题。之所以叫做懒汉模式 * 主要是因为此种方法可以非常明显的lazy loading。 加锁可以实现线程安全
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if(instance==null) {
instance = new LazySingleton();
}
return instance;
}
}
通过对静态工厂方法加锁实现
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if(instance==null) {
instance = new LazySingleton();
}
return instance;
}
}
3 饿汉模式
直接在运行这个类的时候进行一次loading,之后直接访问。显然,这种方法没有起到lazy loading的效果但是不需要用锁就实现线程安全,考虑到前面提到的和静态类的对比,这种方法只比静态类多了一个内存常驻而已。
public class HungerSingleton {
private static HungerSingleton instance = new HungerSingleton();
private HungerSingleton() {
}
public static HungerSingleton getInstance() {
return instance;
}
}
静态内部类不会在单例加载时就加载,而是在调用getInstance()方法时才进行加载,达到了类似懒汉模式的效果,而这种方法又是线程安全的。
public class SingletonDemo {
private static class SingletonHolder{
private static SingletonDemo instance=new SingletonDemo();
}
private SingletonDemo() {
}
public static SingletonDemo getInstance(){
return SingletonHolder.instance;
}
}
5 双重校验法
理论上双重校验锁法是线程安全的,并且,这种方法实现了lazyloading。
简述一下加载类的过程 :STEP 1. 线程A访问getInstance()方法,因为单例还没有实例化,所以进入了锁定块。STEP 2. 线程B访问getInstance()方法,因为单例还没有实例化,得以访问接下来代码块,而接下来代码块已经被线程1锁定。STEP 3. 线程A进入下一判断,因为单例还没有实例化,所以进行单例实例化,成功实例化后退出代码块,解除锁定。STEP 4. 线程B进入接下来代码块,锁定线程,进入下一判断,因为已经实例化,退出代码块,解除锁定。STEP 5. 线程A获取到了单例实例并返回,线程B没有获取到单例并返回Null
public class SingletonCheck {
private volatile static SingletonCheck instance;
private SingletonCheck(){
}
public static SingletonCheck getInstance(){
if(instance==null){
synchronized (SingletonCheck.class){
if(instance==null){
instance=new SingletonCheck();
}
}
}
return instance;
}
}
6枚举法
public enum SingletonEnum {
INSTANCE;
public void otherMethods(){
System.out.println("Something");
}
}
总结 以上这些就是单例模式的实现方法我的实现代码在网盘:http://pan.baidu.com/s/1eRQKXuM