23种设计模式之单例模式(java 实现)

一、概述书接上回,之前我我们讲到原型设计模式。这次我们谈谈单例模式。单例模式是最喜闻乐见的设计模了,因为是 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;
	}

}


2.懒汉模式(线程安全 )

通过对静态工厂方法加锁实现

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;
	}

}


4 静态内部类模式

静态内部类不会在单例加载时就加载,而是在调用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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值