【学亮说】Java实现单例模式的8种方式(你真的搞懂单例模式了吗?)

第一种:饿汉式单例模式 

package com.zhangxueliang.dp.sigleton;

/**
 * 饿汉式单例模式
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午3:39:30
 */
public class Zhangxueliang1 {
	//new一个实例
	private static Zhangxueliang1 instance= new Zhangxueliang1();
	//私有化构造器
	private Zhangxueliang1(){}
	public static Zhangxueliang1 getInstance() {
		return instance;
	}
}

第二种:static代码块创建单例

package com.zhangxueliang.dp.sigleton;

/**
 * 使用static代码块的方式实现饿汉式单例模式
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午3:35:02
 */
public class Zhangxueliang2 {
	private static Zhangxueliang2 instance=null;
	
	private Zhangxueliang2(){}
	
	static {
		instance=new Zhangxueliang2();
	}
	public static Zhangxueliang2 getInstance() {
		return instance;
	}
	
}

 第三种:懒汉式单例模式

package com.zhangxueliang.dp.sigleton;

/**
 * 懒汉式单例模式
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午3:40:34
 */
public class Zhangxueliang3 {

	private static Zhangxueliang3 instance;

	private Zhangxueliang3() {
	}

	public static Zhangxueliang3 getInstance() {
		if (instance == null) {
			//SleepUtil.sleep(1);
			instance = new Zhangxueliang3();
		}
		return instance;
	}

}

第四种:懒汉式+synchronized同步方法

package com.zhangxueliang.dp.sigleton;

/**
 * 懒汉式单例+synchronized同步方法
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午4:02:29
 */
public class Zhangxueliang4 {
	
	private static Zhangxueliang4 instance;
	
	private Zhangxueliang4() {}
	
	public static synchronized Zhangxueliang4 getInstance() {
		if(instance==null) {
			SleepUtil.sleep(10);
			instance = new Zhangxueliang4();
		}
		return instance;
	}
}

第五种:懒汉式 + synchronized同步代码块

package com.zhangxueliang.dp.sigleton;

/**
 * 懒汉式单例 + synchronized同步代码块
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午4:11:06
 */
public class Zhangxueliang5 {
	
	private static Zhangxueliang5 instance;
	
	private Zhangxueliang5() {}
	
	public static Zhangxueliang5 getInstance() {
		if(instance==null) {
			SleepUtil.sleep(1);
			synchronized(Zhangxueliang5.class) {
				instance = new Zhangxueliang5();
			}
		}
		return instance;
	}
}

第六种:双重检查double check

package com.zhangxueliang.dp.sigleton;

/**
 * 双重检查
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午4:25:36
 */
public class Zhangxueliang6 {

	private static volatile Zhangxueliang6 instance;//禁止指令重排
	
	private Zhangxueliang6() {}
	
	public static Zhangxueliang6 getInstance() {
		if(instance==null) {
			SleepUtil.sleep(10);
			synchronized(Zhangxueliang6.class) {
				//双重检查
				if(instance==null) {
					instance = new Zhangxueliang6();
				}
			}
		}
		return instance;
	}
}

第七种:静态内部类方式

package com.zhangxueliang.dp.sigleton;

/**
 * 静态内部类方式实现单例模式
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午4:29:14
 */
public class Zhangxueliang7 {
	
	private Zhangxueliang7() {}
	
	private static class Zhangxueliang7Holder{
		private static final Zhangxueliang7 instance=new Zhangxueliang7();
	}
	
	public static Zhangxueliang7 getInstance() {
		return Zhangxueliang7Holder.instance;
	}
	
}

 第八种:枚举方式创建单例(语法角度堪称完美)

package com.zhangxueliang.dp.sigleton;

/**
 * 语法上是最完美的。可以解决线程同步问题和反序列化(反射)
 * 
 * @Author:Zhang Xueliang
 * 
 * @Date:2020年3月15日 下午4:37:13
 */
public enum Zhangxueliang8 {
	instance;
}

线程安全性测试:

package com.zhangxueliang.dp.sigleton;

public class TestSigtelon {

	public static void main(String[] args) {
		//testEhanSinleton();
		//testStaticSingleton();
		//testLanhanSingleton();
		//testHashcode();
		//testSynMethod();
		//testSyncBlock();
		//testDoubleCheck();
		//testStaticClass();
		testEnum();
	}

	private static void testEnum() {
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
					System.out.println(Zhangxueliang8.instance.hashCode());
			}).start();
		}
	}

	/**
	 * 测试静态内部类创建单例
	 */
	private static void testStaticClass() {
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
					System.out.println(Zhangxueliang7.getInstance().hashCode());
			}).start();
		}
	}

	/**
	 * 测试双重检查
	 */
	private static void testDoubleCheck() {
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
					System.out.println(Zhangxueliang6.getInstance().hashCode());
			}).start();
		}
	}

	/**
	 * 懒汉式单例 + synchronized同步代码块
	 */
	private static void testSyncBlock() {
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
					System.out.println(Zhangxueliang5.getInstance().hashCode());
			}).start();
		}
	}

	/**
	 * 测试懒汉式单例+synchronized同步方法
	 */
	private static void testSynMethod() {
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
					System.out.println(Zhangxueliang4.getInstance().hashCode());
			}).start();
		}
	}

	/**
	 * hashCode相同,不一定是同一个对象
	 */
	private static void testHashcode() {
		System.out.println("通话".hashCode());//1179395
		System.out.println("重地".hashCode());//1179395
	}

	/**
	 * 懒汉式单例模式  存在线程安全问题
	 */
	private static void testLanhanSingleton() {
		for (int i = 0; i < 100; i++) {
			new Thread(()->{
					System.out.println(Zhangxueliang3.getInstance().hashCode());
			}).start();
		}
	}

	/**
	 * 测试static代码块单例模式
	 */
	private static void testStaticSingleton() {
		Zhangxueliang2 z1 = Zhangxueliang2.getInstance();
		Zhangxueliang2 z2 = Zhangxueliang2.getInstance();
		System.out.println(z2==z1);
	}

	/**
	 * 测试饿汉式单例模式
	 */
	private static void testEhanSinleton() {
		Zhangxueliang1 z1 = Zhangxueliang1.getInstance();
		Zhangxueliang1 z2 = Zhangxueliang1.getInstance();
		System.out.println(z2==z1);
	}

}
发布了1608 篇原创文章 · 获赞 932 · 访问量 88万+

猜你喜欢

转载自blog.csdn.net/a772304419/article/details/104888532