Java设计模式之Singleton模式

单例模式详解
本文深入探讨了单例模式的基本概念及其在Java中的多种实现方式,包括饿汉式、线程安全懒汉式、双重检查锁定及按需初始化持有类等,并通过示例代码展示了每种形式的特点。

本概念

Singleton 是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点.对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在.再举个例子,集合中的 set 中不能包含重复的元素,添加到set里的对象必须是唯一的,如果重复的值添加到 set,它只接受一个实例.JDK中正式运用了Singleton模式来实现 set 的这一特性,大家可以查看java.util.Collections里的内部静态类SingletonSet的原代码.其实Singleton是最简单但也是应用最广泛的模式之一,在 JDK 中随处可见.

简单分析

为了实现 Singleton 模式,我们需要的是一个静态的变量,能够在不创建对象的情况下记忆是否已经产生过实例了.静态变量或静态方法都可以在不产生具体实例的情况下直接调用,这样的变量或方法不会因为类的实例化而有所改变

Singleton 模式用来保证在运行的应用程序中,一个Class只是实例化一次,也就是只有一个相应的对象存在。在 web 程序中我们会用一个核心的分配功能的Servlet程序,在这里我们就可以运用这种设计模式了。

  一般Singleton模式通常有几种形式:

  第一种形式:

  定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。

package testSingleton;
public class Singleton {
	private static Singleton instance = new Singleton();
	private Singleton() {
	}

	public static Singleton getInstance() {
		return instance;
	}
	public static void main(String[] args) {
		Singleton singleton = Singleton.getInstance();
		Singleton singleton1 = Singleton.getInstance();
		if (singleton == singleton1) {
			System.out.println("same");
		}else {
			System.out.println();
		}
	}
}

  第二种形式:线程安全、延迟创建的单例

package testSingleton;

public class Singleton {
	private static Singleton instance = null;

	public static synchronized Singleton getInstance() {
		// 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次使用时生成实例,提高了效率!
		if (instance == null)
			instance = new Singleton();
		return instance;
	}
}

  第三种形式:double checked locking singleton ( 仅适用于java 5.0 以上版本。只同步局部代码,多线程高并发访问情况)

package testSingleton;

public class DoubleCheckSingleton {
	// java5.0 修改了内存模型, 可以保证使用volatile 声明的变量对于double checked locking是正确的
	private volatile static DoubleCheckSingleton instance = null;

	public static DoubleCheckSingleton getInstance() {
		if (instance == null) {// check if it is created.
			synchronized (DoubleCheckSingleton.class) {//synchronize create block 
				if (instance == null) {// double check if it is created.
					instance = new DoubleCheckSingleton();
				}
			}
		}
		return instance;
	}
}

第四种形式:Initialization on demand holder (线程安全、延迟创建的单例)

package testSingleton;

public class LazyLoadedSingleton {
	// 当JVM加载LazyLoadedSingleton类时,由于该类没有static属性,所以加载完成后即可返回。
	// 只有第一次调用getInstance()方法时,JVM才会加载LazyHolder类,由于它包含一个static属性singletonInstance,
	// 所以会首先初始化这个变量,该过程不会出现并发问题,这样就实现了一个既线程安全又支持延迟加载的单例模式
	private LazyLoadedSingleton() {
	}

	private static class LazyHolder {
		private static final LazyLoadedSingleton singletonInstance = new LazyLoadedSingleton();
	}

	public static LazyLoadedSingleton getInstance() {
		return LazyHolder.singletonInstance;
	}
}


测试

package test4JavaStudy.thread;

//线程安全的Singleton模式  
class Singleton {
	private static Singleton sample;

	public synchronized static Singleton getInstance() {
		if (sample == null) {
			// 为了放大Singleton模式的线程不安全性
			Thread.yield();
			sample = new Singleton();
		}
		return sample;
	}
}

public class TestThread extends Thread {
	public void run() {
		Singleton singleton = Singleton.getInstance();
		System.out.println(singleton.hashCode());
	}

	public static void main(String[] args) {
		Thread threads[] = new Thread[5];
		for (int i = 0; i < threads.length; i++)
			threads[i] = new TestThread();
		for (int i = 0; i < threads.length; i++)
			threads[i].start();
	}
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值