欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java单例模式的几种实现方式

程序员文章站 2022-03-07 22:41:01
...

(1)饿汉模式(线程安全、调用效率高、但不能延时加载)

package com.si.single1;

/*
 * 饿汉式
 * 立即创建
 * 线程安全
 * */
public class SingleDemo {

	private static SingleDemo instance = new SingleDemo();

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

	// 创造公有方法调用instance
	public static SingleDemo getInstance() {
		return instance;
	}
}

一上来就把单例对象创建出来了,要用的时候直接返回即可,这种可以说是单例模式中最简单的一种实现方式。但是问题也比较明显。单例在还没有使用到的时候,初始化就已经完成了。也就是说,如果程序从头到位都没用使用这个单例的话,单例的对象还是会创建。这就造成了不必要的资源浪费。所以不推荐这种实现方式。

(2)懒汉式(线程不安全,调用效率不高,但是能延时加载):

package com.si.single1;

/*
 * 懒汉式
 * 使用的时候才会创建
 * 线程不安全
 * */
public class SingleDemo1 {

	private static SingleDemo1 instance;

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

	// 调用的时候才会创建实例,两个以上线程同时进入时,线程不安全
	public static SingleDemo1 getInstance() {
		if (instance == null) {
			instance = new SingleDemo1();
		}
		return instance;
	}
}

(3)加锁懒汉式(线程安全,调用效率不高,但是能延时加载):

package com.si.single1;

/*
 * 加锁懒汉式
 * 使用的时候才会创建
 * 线程安全
 * */
public class SingleDemo1 {

	private static SingleDemo1 instance;

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

	// 调用的时候才会创建实例,两个以上线程同时进入时,线程安全
	public static synchronized SingleDemo1 getInstance() {
		if (instance == null) {
			instance = new SingleDemo1();
		}
		return instance;
	}
}

 

(4)Double CheckLock实现单例:DCL也就是双重锁判断机制-双重验证懒汉式(由于JVM底层模型原因,偶尔会出问题,不建议使用):

package com.si.single1;

//DCL(双重验证懒汉式)
public class SingleDemo2 {

	private static SingleDemo2 instance;

	private SingleDemo2() {}

	public static SingleDemo2 getInstance() {
		if (instance == null) {
			// 改进加锁懒汉式,锁加在if判断语句后,可减少锁的使用
			synchronized (SingleDemo2.class) {
				if (instance == null) {
					instance = new SingleDemo2();
				}
			}
		}
		return instance;
	}
}

(5)静态内部类实现模式(线程安全,调用效率高,可以延时加载)

package com.si.single1;

public class SingleDemo3 {

	private SingleDemo3() {
	}

	// 创建内部类
	private static class Inner {
		private static SingleDemo3 instance = new SingleDemo3();
	}

	// 创建公有方法,使用的时候调用
	public static SingleDemo3 getInstance() {
		return Inner.instance;
	}
}

(6)枚举类

package com.si.single1;

public class SingleDemo4 {

	private SingleDemo4() {
	}

	// 创建枚举类
	private static enum Inner {
		INSTANCE;
		// 此处定义的实例不能用static修饰,因为在构造器中会对其进行初始化。
		private SingleDemo4 instance;

		private Inner() {
			instance = new SingleDemo4();
		}

		// 此方法不能用static修饰,静态方法不能调用非静态变量。
		public SingleDemo4 getInstance() {
			return instance;
		}
	}

	// 外部调用方法
	public static SingleDemo4 getInnerInstance() {
		return Inner.INSTANCE.getInstance();
	}
}