java 设计模式 --singleton 单例模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HZMand1/article/details/83818303

Singleton 单例模式:

        有些对象只需要一个,比如:线程池、缓存、对话框、处理偏好设置和注册表的对象、日志对象,充当打印机、显卡等设备的驱动程序的对象。

        这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

        这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

应用实例: 

1、要求生产唯一序列号。

2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。

3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。

4、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来;

5、创建的一个对象需要消耗的资源过多,比如数据库的连接等。

懒汉式

以下代码是懒汉式的线程安全 和不安全的 实现 和验证:

public class SingletonTest {

	public static void main(String[] args) {
		SingletonTest singletonTest = new SingletonTest();

		// esay singleton
		// singletonTest.easySingleton();

		// singleton one  false 单线程  true 是多线程
//		singletonTest.singletonOneTest(true);
		
		// singleton two
		singletonTest.singletonOneTwo();
	}

	public void easySingleton() {
		// 不合法的构造函数
		// 编译时错误:构造函数 SingleObject() 是不可见的
		// SingleObject object = new SingleObject();

		// 获取唯一可用的对象
		SingletonObject object = SingletonObject.getInstance();

		// 显示消息
		object.test();
	}

	public void singletonOneTest(boolean isMultipe) {

		try {
			// 单线程
			if (!isMultipe) {
				Thread thread = new ThreadTest();
				thread.start();
			} else {
		        for (int i = 0; i < 200; i++) {
		        	Thread t4 = new ThreadTest();
		        	t4.start();
				}
			}
		} catch (Exception e) {
			System.out.println("线程异常了");
		}
	}
	
	public void singletonOneTwo() {
		for (int i = 0; i < 200; i++) {
        	Thread t4 = new ThreadTwoTest();
        	t4.start();
		}
	}
}

class ThreadTest extends Thread {
	private static int num = 0;
	public ThreadTest(){
        num++;
    }
	
	public void run() {
		try {
			System.out.println("创建的第"+num+"个线程");
			SingletonOne.getInstance();
		} catch (Exception e) {
			System.out.println("线程运行中断异常");
		}
	}
}

class ThreadTwoTest extends Thread {
	private static int num = 0;
	public ThreadTwoTest(){
        num++;
    }
	
	public void run() {
		try {
			System.out.println("创建的第"+num+"个线程");
			SingletonTwo.getIntance();
		} catch (Exception e) {
			System.out.println("线程运行中断异常");
		}
	}
}
/**
 * 懒汉式,线程不安全
 * 这种方式是最基本的实现方式;
 * 这种实现最大的问题就是不支持多线程。
 * 因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
 * 这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
 */
public class SingletonOne {
	private static int count = 0;
	//定义对象
	private static SingletonOne instance = null;
	//私有化初始方法
	private SingletonOne(){}
	
	//实例化对象
	public static SingletonOne getInstance(){
		try {
			if(null == instance) {
				count ++;
				System.out.println("Singleton 对象第 " + count + "次创建。");
				instance = new SingletonOne();
			}
		} catch (Exception e) {
			System.err.println("线程异常");
		}
		return instance;
	}
}
/**
 * 懒汉式,线程安全
 * 这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
 * 优点:第一次调用才初始化,避免内存浪费
 * 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
 */
public class SingletonTwo {
	private static int count = 0;
	private static SingletonTwo instance = null;
	private SingletonTwo() {}
	
	public static synchronized  SingletonTwo getIntance() {
		try {
			if(null == instance) {
				count ++;
				System.out.println("Singleton 对象第 " + count + "次创建。");
				instance = new SingletonTwo();
			}
		} catch (Exception e) {
			System.err.println("线程异常");
		}
		return instance;
	}
}

3.饿汉式

常用的 一种方式 ,在类加载的时候就开始初始化,所以这种方式很耗内存。

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

4、双检锁/双重校验锁(DCL,即 double-checked locking)

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

总结下:

第一第二中肯定是建议少用的,第三种饿汉式 感觉还可以,第四种 双检锁 就更稳定点。

猜你喜欢

转载自blog.csdn.net/HZMand1/article/details/83818303