java学习笔记-设计模式之五种单例模式实现效率测试

在前两天的学习中主要对单例模式完成了五种实现,并针对反射及反序列化漏洞进行防止,最后对五种实现模式的效率进行测试。

五种最终实现单例模式代码如下:

1、懒汉式实现单例模式:

package com.zwh.gof23.singleton;

import java.io.Serializable;

/**
 * 懒汉式到单例模式(防序列化及反射漏洞)
 * @author zwh
 * 特点:
 * 1、延迟加载,在调用到getInstance方法时才加载。资源利用率高
 * 2、调用getInstance方法时需要同步,并发效率较低
 */
public class SingletonPatternSlackerNew implements Serializable{
	//实例不初始化,需要时再进行初始化
	private static SingletonPatternSlackerNew instance;
	private static int  count = 0;
	//私有化构造器
	private SingletonPatternSlackerNew(){
		
		synchronized (SingletonPatternSlackerNew.class) {
			if(count > 0){ 
				throw new RuntimeException("创建了两个实例"); 
				} 
			count++; 
			}
		//多次调用时,抛出异常
		if(instance!=null){
			throw new RuntimeException("已存在实例,别想用反射来搞我!");
		}
	}
	
	/**
	 * 初始化类的实例,并保证在调用本方法时才会创建实例,保证线程安全。
	 * @return
	 */
	public static synchronized SingletonPatternSlackerNew getInstance(){
		if(null == instance){
			instance = new SingletonPatternSlackerNew();
		}
		return instance;
	}
	
	/**
	 * 防止被反序列化破解单例
	 * @return
	 */
	private Object readResolve(){
		return instance;
	}
}

2、饿汉式单例模式实现:

package com.zwh.gof23.singleton;
/**
 * 单例模式(饿汉式)
 * 1、构造器私有化
 * 2、类初始化时立即加载。
 * 特点:
 * 1、线程安全
 * 2、调用效率高
 * 3、不能延时加载
 * @author zwh
 *
 */
public class SingletonPatternStarving {
	//类初始化时就加载这个对象(static关键字),此时不涉及多个线程对象访问该对象的问题,
	//虚拟机保证只会加载一次该类,肯定不会发生并发访问的问题。
	//但是如果只是加载本类,而不是要调用geiInstance(),甚至永远没有使用,则造成资源浪费
	private static SingletonPatternStarving instanse=new SingletonPatternStarving();
	
	//构造器私有化
	private SingletonPatternStarving(){
	}
	
	public static SingletonPatternStarving getInstance(){
		return instanse;
	}
}

3、双重检测锁实现单例模式:

 

 

 

 

 

 

 

 

 

package com.zwh.gof23.singleton;

/**
 * 双重检测锁单例模式 将同步内容放到if条件内,只有第一次创建实例时需要进行同步,提高效率
 * 
 * @author zwh
 * 
 */
public class SingletonPatternDoubleCheckLock {

	// 声明变量
	private static SingletonPatternDoubleCheckLock instance;

	/**
	 * 全局访问方法,获取类的实例
	 * 
	 * @return
	 */
	public static SingletonPatternDoubleCheckLock getInstance() {
		if (null == instance) {
			SingletonPatternDoubleCheckLock sc;
			synchronized (SingletonPatternDoubleCheckLock.class) {
				sc=instance;
				if(null==sc){
					synchronized (SingletonPatternDoubleCheckLock.class) {
						if(null==sc){
							sc=new SingletonPatternDoubleCheckLock();
						}
					}
					instance=sc;
				}
			}
		}
		return instance ;
	}

	// 私有化构造器
	private SingletonPatternDoubleCheckLock() {
	}

}

4、静态内部类实现单例模式:

package com.zwh.gof23.singleton;

/**
 * 静态内部类实现单利模式
 * 1、只有调用全局访问方法时,才会初始化单例对象。可以延迟加载
 * 2、加载类时天然的线程安全
 * 3、同时具备懒汉式和饿汉式的优势
 * 
 * @author zwh
 * 
 */
public class SingletonPatternInnerStaticClass {

	/**
	 * 静态内部类中声明并初始化外部类的实例
	 * 
	 * @author zwh
	 * 
	 */
	private static class SingletonClassInstance {
		private static final SingletonPatternInnerStaticClass instance = 
				new SingletonPatternInnerStaticClass();
	}

	/**
	 * 全局获取单例的方法
	 * 
	 * @return
	 */
	public static SingletonPatternInnerStaticClass getInstance() {
		return SingletonClassInstance.instance;
	}

	/**
	 * 构造方法私有化
	 */
	private SingletonPatternInnerStaticClass() {
	}
}

5、枚举实现单例模式:

package com.zwh.gof23.singleton;
/**
 * 使用枚举实现单例模式
 * @author zwh
 * 1、调用效率高
 * 2、避免反射漏洞
 * 3、没有延迟加载
 */
public enum SingletonPatternEnum {

	/**
	 * 定义一个元素,代表一个实例
	 */
	INSTANCE;
	
	/**
	 * 对枚举元素的操作
	 */
	public void singletonOperation(){
		
	}
}

 

测试代码:

package com.zwh.gof23.singleton;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.CountDownLatch;

/**
 * 单例模式测试类,测试不同实现方式的效率
 * @author zwh
 * 
 */
public class TestClientForEffictive {

	final static int threadNum=100;
	
	
	
	public static void main(String[] args) throws InterruptedException  {
		testSingletonPatternSlackerNew();
		testSingletonPatternStarving();
		testSingletonPatternDoubleCheckLock();
		testSingletonPatternInnerStaticClass();
		testSingletonPatternEnum();
	} 
	
	/**
	 * 测试懒汉式单例模式效率
	 * @throws InterruptedException
	 */
	private static void testSingletonPatternSlackerNew() throws InterruptedException{
		
		final CountDownLatch countDownLatch=new CountDownLatch(threadNum);
		long start=System.currentTimeMillis();
		for(int i=0;i<threadNum;i++){
			new Thread(new Runnable() {
				public void run() {
					for(int i=0;i<100000;i++){
						SingletonPatternSlackerNew instance=SingletonPatternSlackerNew.getInstance();
					}
					countDownLatch.countDown();
				}
			}).start();
		}
		countDownLatch.await();
		long end=System.currentTimeMillis();
		System.out.println("懒汉式单例模式实现耗时:"+(end-start));
		
		
		
	}
	
	/**
	 * 测试饿汉式单例模式效率
	 * @throws InterruptedException
	 */
	private static void testSingletonPatternStarving() throws InterruptedException{

		final CountDownLatch countDownLatch=new CountDownLatch(threadNum);
		long start=System.currentTimeMillis();
		for(int i=0;i<threadNum;i++){
			new Thread(new Runnable() {
				public void run() {
					for(int i=0;i<100000;i++){
						SingletonPatternStarving instance=SingletonPatternStarving.getInstance();
					}
					countDownLatch.countDown();
				}
			}).start();
		}
		countDownLatch.await();
		long end=System.currentTimeMillis();
		System.out.println("饿汉式单例模式实现耗时:"+(end-start));
	}
	
	/**
	 * 测试双重检测锁实现的单例模式效率
	 * @throws InterruptedException
	 */
	private static void testSingletonPatternDoubleCheckLock() throws InterruptedException{
		final CountDownLatch countDownLatch=new CountDownLatch(threadNum);
		long start=System.currentTimeMillis();
		for(int i=0;i<threadNum;i++){
			new Thread(new Runnable() {
				public void run() {
					for(int i=0;i<100000;i++){
						SingletonPatternDoubleCheckLock instance=SingletonPatternDoubleCheckLock.getInstance();
					}
					countDownLatch.countDown();
				}
			}).start();
		}
		countDownLatch.await();
		long end=System.currentTimeMillis();
		System.out.println("双重检测锁式单例模式实现耗时:"+(end-start));
	}
	
	/**
	 * 测试静态内部类实现的单例模式效率
	 * @throws InterruptedException
	 */
	private static void testSingletonPatternInnerStaticClass() throws InterruptedException{
		final CountDownLatch countDownLatch=new CountDownLatch(threadNum);
		long start=System.currentTimeMillis();
		for(int i=0;i<threadNum;i++){
			new Thread(new Runnable() {
				public void run() {
					for(int i=0;i<100000;i++){
						SingletonPatternInnerStaticClass instance=SingletonPatternInnerStaticClass.getInstance();
					}
					countDownLatch.countDown();
				}
			}).start();
		}
		countDownLatch.await();
		long end=System.currentTimeMillis();
		System.out.println("静态内部类式单例模式实现耗时:"+(end-start));
	}
	
	/**
	 * 测试枚举实现的单例模式效率
	 * @throws InterruptedException
	 */
	private static void testSingletonPatternEnum() throws InterruptedException{
		final CountDownLatch countDownLatch=new CountDownLatch(threadNum);
		long start=System.currentTimeMillis();
		for(int i=0;i<threadNum;i++){
			new Thread(new Runnable() {
				public void run() {
					for(int i=0;i<100000;i++){
						SingletonPatternEnum instance=SingletonPatternEnum.INSTANCE;
					}
					countDownLatch.countDown();
				}
			}).start();
		}
		countDownLatch.await();
		long end=System.currentTimeMillis();
		System.out.println("枚举式单例模式实现耗时:"+(end-start));
	}
	
}

输出结果:

懒汉式单例模式实现耗时:209
饿汉式单例模式实现耗时:21
双重检测锁式单例模式实现耗时:25
静态内部类式单例模式实现耗时:31
枚举式单例模式实现耗时:25

不同环境测试结果可能不同,此结果仅供参考。可得出懒汉式单例模式实现效率最低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云间歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值