Java设计模式之Singleton模式

来源:互联网 发布:plsql oracle数据迁移 编辑:程序博客网 时间:2024/06/05 06:12

本概念

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



 

原创粉丝点击