剑指offer 面试题2:单例模式(java实现)

Java 单例模式

摘要:博主在学习剑指offer过程中,结合另外一位道友总结Java的单例模式:https://www.cnblogs.com/cielosun/p/6582333.html


如有不足,希望大佬指点:

应用单例模式的场景:由于程序的设计,我们需要某个类同时且最多只需保留一个对象,此时我们就需要单例模式;

特点:

  1. 单例只能有一个实例;
  2. 单例类必须创建自己的唯一实例;
  3. 单例类必须向其他对象提供这一实例;

module1:不好的解法一:只适用于单线程环境(又称懒汉模式)

public class Singleton1 {
	private Singleton1() {
	}

	private static Singleton1 singleton = null;

	public static Singleton1 getInstance() {
		if (singleton == null) {
			singleton = new Singleton1();
		}
		return singleton;
	}
}

缺陷:懒汉模式在多线程的情况下存在问题:设想两个线程同时运行至判断singleton是否为null,并且instance的确没有创建的时候,那么两个线程都会创建singleton实例,此时便不符合单例模式了;解决方案:加锁,使用sychronized;

module2:不好的解法二:线程安全的懒汉模式,但是效率不高;

public class Singleton1 {
	private Singleton1() {
	}

	private static Singleton1 singleton = null;

	public static synchronized Singleton1 getInstance() {
		if (singleton == null) {
			singleton = new Singleton1();
		}
		return singleton;
	}
}

缺陷:此时的效率不是很高,因为sychronized在保证单线程访问的情况下,却使得效率降低;1)加锁是一个非常耗时的操作 2)假设有两个线程同时想创建一个实例,由于同一时刻只有一个线程能够得到同步锁,当第一个线程上锁时,另外一个线程只能等待,且上锁线程占据其他资源,降低效率。更加尴尬的是第二个线程拿到“钥匙”时,实例已经被第一个线程创建出来了。

module3:可行的解法三:加同步锁两次判断实例是否存在(双重效验锁法)

public class Singleton1 {
	private Singleton1() {
		System.out.println("创建弯沉");
	}

	private static Singleton1 singleton;

	public static Singleton1 getInstance() {
		if (singleton == null) {
			synchronized (Singleton1.class) {
				if (singleton == null) {
					singleton = new Singleton1();
				}
			}
		}
		return singleton;
	}
}

缺陷:module3加锁机制来保证最多只有一个实例,并且用两个if来实现提高效率;这样的代码实现起来比较复杂,容易出错;

我们可以使用java中的static 特性(确保只是使用一次)来实现单例模式;

module4:强烈推荐的解法一:利用静态构造函数(饿汉模式)

public class Singleton1 {
	private Singleton1() {
	}

	private static Singleton1 singleton = new Singleton1();

	public static Singleton1 getInstance() {
		return singleton;
	}
}

缺陷:代码虽然已经十分的简洁,但是没有达到Lazy loading的效果:静态函数的调用不是程序员掌控的,会过早地创建实例,从而降低内存的使用效率:

module5:强烈推荐的解法二:实现按需创建实例

public class Singleton1 {
	private Singleton1() {
	}

	private static class Nested {
		private static Singleton1 instance = new Singleton1();
	}

	public static Singleton1 getInstance() {
		return Nested.instance;
	}
}

看到这里,你已经无敌啦!去吧,骚年。如果有帮到你,请点赞哦!如果有不足,欢迎指出;

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值