Java-------单例设计模式

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

一.懒汉式    ------双重检查

package com.kennosaur.syn;
/**
 * 单例设计模式:外部使用时,确保一个类只有一个对象
 * @author Administrator
 *
 */
public class Synchronized02 {

	public static void main(String[] args) {
		/*
		Jvm jvm1 = Jvm.getInstance();
		Jvm jvm2 = Jvm.getInstance();
		//单例模式单线程中地址一样
		System.out.println(jvm1);  //com.kennosaur.syn.Jvm@7852e922
		System.out.println(jvm2);  //com.kennosaur.syn.Jvm@7852e922
		*/
		
		/*
		//多线程可能出现地址不一样的情况
		JvmThread thread1 = new JvmThread(100);
		JvmThread thread2 = new JvmThread(500);
		thread1.start();   //Thread-0--->创建:com.kennosaur.syn.Jvm@25303d5c
		thread2.start();   //Thread-1--->创建:com.kennosaur.syn.Jvm@31c6e548
		*/
		
		/*
		//多线程可能出现地址不一样的情况,加上synchronized同步方法后,地址一样
		JvmThread thread1 = new JvmThread(100);
		JvmThread thread2 = new JvmThread(500);
		thread1.start();   //Thread-1--->创建:com.kennosaur.syn.Jvm@6b98d4
		thread2.start();   //Thread-0--->创建:com.kennosaur.syn.Jvm@6b98d4
		*/
		
		/*
		//多线程可能出现地址不一样的情况,加上synchronized同步块后,地址一样----注意Jvm.class(字节码信息)
		JvmThread thread1 = new JvmThread(100);
		JvmThread thread2 = new JvmThread(500);
		thread1.start();   //Thread-0--->创建:com.kennosaur.syn.Jvm@31c6e548
		thread2.start();   //Thread-1--->创建:com.kennosaur.syn.Jvm@31c6e548
		*/
		
		//多线程可能出现地址不一样的情况,加上synchronized同步块后,地址一样----注意Jvm.class(字节码信息)   
		//在同步块外再加一层判断,提高已存在对象的访问速率
		JvmThread thread1 = new JvmThread(100);
		JvmThread thread2 = new JvmThread(500);
		thread1.start();   //Thread-1--->创建:com.kennosaur.syn.Jvm@6b98d4
		thread2.start();   //Thread-0--->创建:com.kennosaur.syn.Jvm@6b98d4
		
	}

}

class JvmThread extends Thread{
	private long time;
	public JvmThread() {
	}
	public JvmThread(long time) {
		this.time = time;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+"--->创建:"+Jvm.getInstance(time));
	}
	
}

/**
 * 单例设计模式
 * 确保一个类只有一个对象
 * 懒汉式    double checking---双重检查
 * 1.构造器私有化,避免外部直接创建对象
 * 2.声明一个静态变量
 * 3.创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
 * @author Administrator
 *
 */
class Jvm{
	//2.声明一个静态变量
	private static Jvm instance = null;
	//1.构造器私有化,避免外部直接创建对象
	private Jvm() {
		
	}
	//3.创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
	/*
	public static Jvm getInstance() {
		if(null==instance) {
			instance = new Jvm();
		}
		return instance;
	}*/
	
	/*
	public static Jvm getInstance(long time) {
		if(null==instance) {
			try {
				Thread.sleep(time);   //延时,故意放大发生错误的概率
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			instance = new Jvm();
		}
		return instance;
	}*/
	
	/*
	public static synchronized Jvm getInstance(long time) {
		if(null==instance) {
			try {
				Thread.sleep(time);   //延时,故意放大发生错误的概率
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			instance = new Jvm();
		}
		return instance;
	}*/
	
	/*
	public static Jvm getInstance(long time) {
		//效率不高,存在对象也需要等待
		synchronized(Jvm.class) {
			if(null==instance) {
				try {
					Thread.sleep(time);   //延时,故意放大发生错误的概率
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				instance = new Jvm();
			}
			return instance;
		}
	}*/
	
	public static Jvm getInstance(long time) {
		if(null==instance) {   //提高效率  提高已经存在对象的访问效率
			synchronized(Jvm.class) {
				if(null==instance) {
					try {
						Thread.sleep(time);   //延时,故意放大发生错误的概率
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					instance = new Jvm();
				}
			}
		}
		return instance;
	}
	
	
}

二.饿汉式

package com.kennosaur.syn;
/**
 * 单例创建的方式
 * 1.懒汉式    ----注意双重检查
 *   a.构造器私有化;
 *   b.声明私有的静态属性;
 *   c.对外提供访问属性的静态方法,确保该对象存在
 * @author Administrator
 *
 */
public class MyJvm {
	private static MyJvm instance;
	private MyJvm() {
		
	}
	public static MyJvm getInstance() {
		if(null==instance) { //提高效率
			synchronized (Jvm.class) {
				if (null==instance) {  //保证安全
					instance = new MyJvm();
				}
			}
		}
		return instance;
	}
}

/**
 * 2.饿汉式      ----类使用时加载
 *   a.构造器私有化;
 *   b.声明私有的静态属性,同时创建该对象;
 *   c.对外提供访问属性的静态方法;
 * @author Administrator
 *
 */
class MyJvm2 {
	private static MyJvm2 instance = new MyJvm2();
	private MyJvm2() {
		
	}
	public static MyJvm2 getInstance() {
		return instance;
	}
}

/**
 * 类在使用的时候才加载,内部类JVMholder延缓了加载时机
 * 调用到getInstance方法时,才new实例
 * @author Administrator
 *
 */
class MyJvm3 {
	private static class JVMholder{
		private static MyJvm3 instance = new MyJvm3();
	}
	private MyJvm3() {
		
	}
	public static MyJvm3 getInstance() {
		return JVMholder.instance;
	}
}


三.在jdk中的Runtime类就用到了单例模式中的饿汉式创建方法

猜你喜欢

转载自blog.csdn.net/Miracle_Gaaral/article/details/89116100