设计模式之一:单例模式

单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

单例模式分为:饿汉模式和懒汉模式

一  饿汉模式

  1 饿汉模式  ---静态常量(可用)

/**
 * 单例模式 --饿汉模式--静态常量(可以用)
 * y:在类加载的时候就进行了类的实例化,避免了线程的同步问题
 * n:同时,在类加载的时候就进行了实例化,没有达到懒加载的效果,万一之后不用,就会浪费内存
 *
 */
public class SingletonTest1 {
	private  static final SingletonTest1 instance=new SingletonTest1();
	private SingletonTest1() {}
	public static SingletonTest1 getInstance() {
		return instance;
	}
}

 y:在类加载的时候就进行了类的实例化,避免了线程的同步问题
 n:同时,在类加载的时候就进行了实例化,没有达到懒加载的效果,万一之后不用,就会浪费内存

  2 饿汉模式  ---静态代码块(可用)

/**
 * 单例模式 --饿汉模式--静态代码块的使用(可以用)
 * 和静态常量差不多,在类加载的时候加载静态代码块进行实例化  
 *
 */
public class SingletonTest2 {
	private  static  SingletonTest2 instance=null;
	static {
		instance=new SingletonTest2();
	}
	private SingletonTest2() {}
	public static SingletonTest2 getInstance() {
		return instance;
	}
}

和静态常量差不多,在类加载的时候加载静态代码块进行实例化  

二 懒汉模式

  1 懒汉模式:普通模式(不用,线程不安全)

/**
 * 懒汉模式  --普通模式(不用,线程不安全)
 * 刚开始不进行实例化,等需要的时候--》有就调用,没有就进行实例化。
 * y:这个模式实现了懒加载.单线程下是有效的
 * n:但是在多线程下不安全----当一个线程在if(instance == null) 这个判断还没有往下进行实例化,又有一个线程进行判断了,这个时候就会进行两次实例化,不再单例。
 */
public class SingletonTest3 {
	private static SingletonTest3 instance = null;
	private SingletonTest3() {}
	public static SingletonTest3 getInstance() {
		if(instance == null) {
			instance = new SingletonTest3();
		}
		return instance;
	}
}

刚开始不进行实例化,等需要的时候--》有就调用,没有就进行实例化。
 y:这个模式实现了懒加载.单线程下是有效的
 n:但是在多线程下不安全----当一个线程在if(instance == null) 这个判断还没有往下进行实例化,又有一个线程进行判断了,这个时候就会进行两次实例化,不再单例。

 2  懒汉模式:--使用锁(同步方法-锁加在方法上) (可用,不推荐)

public class SingletonTest4 {
	private static SingletonTest4 instance = null;
	private SingletonTest4() {}
	public static synchronized SingletonTest4 getInstance() {
		if(instance == null) {
			instance = new SingletonTest4();
		}
		return instance;
	}

}

y:这种懒汉模式实现了线程同步,不会发生因为多线程的问题出现多个实例的问题
n: 但是这种方式的效率太低了,因为主要是对实例化进行线程同步的,在instance不是null之后,直接return instance不需要进行同步加锁。

3 懒汉模式 :--同步代码块(在代码块上加锁)(不可用)

public class SingletonTest5 {
	private static SingletonTest5 instance=null;
	private SingletonTest5() {}
	public static SingletonTest5 getInstance() {
			if(instance == null) {
				synchronized (SingletonTest5.class) {
					instance=new SingletonTest5();
			}
		}
		return instance;
	}
}

   由于同步方法的效率太低,所以使用同步代码块,但是使用这种和SingletonTest3出现相同的问题,在if(instance == null)那块线程不同部

4 懒汉模式:双重检查(推荐用) (两个if判断,对instance=null之后进行加锁,然后再判断null,再实例化)

public class SingletonTest6 {
	private static SingletonTest6 instance = null;
	private SingletonTest6() {}
	public static SingletonTest6 getInstance() {
		if(instance == null) {
			synchronized (SingletonTest6.class) {
				if(instance == null) {
					instance=new SingletonTest6();
				}
			}
		}
		return instance;
	}
}

y:集合以上几种的优点 线程安全,延迟加载,效率高

三:其他单例模式

1 直接使用静态内部类(推荐使用)

public class SingletonTest7 {
	private SingletonTest7() {}
	private static class SingletonTest7Instance{
		private static final SingletonTest7 instance = new SingletonTest7();
	}
	public static SingletonTest7 getInstance() {
		return SingletonTest7Instance.instance;
	}
}

类加载的时候就会加载静态方法,直接实例化

2 枚举(其实就是静态常量)

public enum SingletonTest8 {
	INSTANCE;
	/**
	 * 其他方法
	 */
	public void test() {
		System.out.println("普通方法");
	}
}

--INSTANCE就是静态常量(是public final static 修饰的成员变量),只会创建一次,还实现了线程安全(但是自己不常用,听说大佬用);

四、使用场景:

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

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

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

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

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

二十三种设计模式之单例模式完成!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值