设计模式(单例模式)

java23种设计模式
里氏代换原则,适配器模式

单例模式:一个类只能有一个实例

①对于单例类来说,可以有其他的属性,也可以有静态和非静态的其他方法。
②要求按照既定的步骤来执行,就能实现一个单例:
1)私有构造方法
2)提供一个私有的属性,该属性是该类一个静态私有对象。
3)提供一个静态的getter方法,供外界访问。
4)理论上,懒汉式要优于饿汉式,提高了空间的利用率,但是在实际开发中,使用饿汉式居多。懒汉式有线程安全问题,对于懒汉式来说需要解决线程的安全问题,比对空间利用率来说,线程安全问题更难解决。

饿汉式:类一加载就创建实例

弊端:用类的其他方法时,也会创建这个类的实例

class SingleB{//饿汉式。一存在就创建
	//私有构造方法
	private SingleB() {}
	//私有静态实例属性
	private static SingleB instance = new SingleB();
	//公有静态get方法
	public static SingleB getInstance() {
		return instance;
	}
}

懒汉式:什么时候用什么时候创建

解决了饿汉式问题,但是存在线程安全问题。
因为在if判断时会产生线程安全问题。
解决线程问题:加锁,但是加锁就是单线程了,运行速度会慢,我们只需要在他第一次创建的时候进行控制。

class SingleAPlus{
	private SingleAPlus(){
	}
	private static SingleAPlus instance = null;
	public static SingleAPlus getInstance() {
		// 第一层检查,多线程中可能有很多线程都进去if
		if (instance == null) {
			synchronized (SingleAPlus.class) {
				//判断是否存在实例
				//如果没有第二层检查,那么第一个线程创建完对象释放锁后,后面进入对象也会创建对象,会产生多个对象。因为进入第一层的线程可能有很多
				if (instance == null) {
					try {
						Thread.sleep(100);//为了扩大这个问题,所以加睡眠。测试时使用,真实使用要删除这句。
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					instance = new SingleAPlus();
				}
			} 
		}
		return instance;
	}
}

完整代码

/**
 * 作者: 帅的一批
 * 学习:设计模式 23种
 * 内容:单例模式
 * 		前提:一个类只能有一个实例
 * 			饿汉式:上来就创建对象
 * 			懒汉式:用的时候才创建对象
 * 				懒汉式不用每次都创建对象,但是存在线程安全问题
 * 				怎么产生线程安全?同样道理。在if条件里,多线程运行可能会多个进入if然后进行操作
 * 				解决:加锁,但是加锁就是单线程了,运行速度会慢,我们只需要在他第一次创建的时候进行控制,所以可以再加一层if判断
 */
public class SingleTonStudy1 {
	public static void main(String[] args) {
		//懒汉式
		SingleA sA = SingleA.getInstance();
		SingleA sA2 = SingleA.getInstance();
		System.out.println(sA==sA2);
		//饿汉式
		SingleB sB = SingleB.getInstance();
		SingleB sBB = SingleB.getInstance();
		System.out.println(sB==sBB);
		//懒汉式线程安全问题,创建两个线程同时抢这创建这个类的实例
		new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				SingleAPlus s1 = SingleAPlus.getInstance();
				System.out.println(s1);
			}
		}.start();
		new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				SingleAPlus s2 = SingleAPlus.getInstance();
				System.out.println(s2);
			}
		}.start();
	}
}
class SingleA{ //什么时候用,什么时候创建
	private SingleA(){
		//构造方法私有化
	}
	//静态实例成员
	private static SingleA instance = null;
	//公有get方法,静态
	public static SingleA getInstance() {
		//判断是否存在实例
		if (instance == null) {
			instance = new SingleA();
		}
		return instance;
	}
}

class SingleB{//饿汉式。一存在就创建
	//私有构造方法
	private SingleB() {}
	//私有静态实例属性
	private static SingleB instance = new SingleB();
	//公有静态get方法
	public static SingleB getInstance() {
		return instance;
	}
}

class SingleAPlus{
	private SingleAPlus(){
	}
	private static SingleAPlus instance = null;
	public static SingleAPlus getInstance() {
		if (instance == null) {
			synchronized (SingleAPlus.class) {
				//判断是否存在实例
				if (instance == null) {
					try {
						Thread.sleep(100);//为了扩大这个问题,所以加睡眠
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					instance = new SingleAPlus();
				}
			} 
		}
		return instance;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值