单例模式超全整理(面试中常见的题目)

单例模式
单例模式的特点:

一是某个类只能有一个实例

二是它必须自行创建这个实例

三是它必须自行向整个系统提供这个实例
应用情况:对于多个对象使用同一个配置信息时,就需要保证该对象的唯一性。

如何保证对象的唯一性

一不允许其他程序用new创建该类对象那个。

二在该类创建一个本类实例

三对外提供一个方法让其他程序可以获取该对象

实现的方法:

一是构造函数私有化

二是类定义中含有一个该类的静态私有对象

三是该类提供了一个静态的公共的函数用于创建或获取它本身的静态私有对象

方法一    饿汉式

public class Person1 {
//定义该类的静态私有对象
	private static final Person1 person1 =new Person1();
	//构造函数私有化
	private Person1(){
		}
//一个静态的公共的函数用于创建或获取它本身的静态私有对象
	public static Person1 getPerson1() {
		return person1;
	}
}

该方法虽然在多线程下也能正确运行但是不能实现延迟加载(什么是延迟加载?

资源效率不高,可能getPerson1()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化

方法二    懒汉式
 

 
public class Person1 {
	private static Person1 person1 =null;
	private Person1(){
		}
	public static Person1 getPerson1() {
		if(person1==null){
		person1=new Person1();
		}
		return person1;
	}
}

该方法只能在单线程下运行,当在多线程下运行时可能会出现创建多个实例的情况。

对该方法可以进行优化

懒汉式 (优化一)

public class Person1 {
	private static Person1 person1 =null;
	private Person1(){
		}
	public static synchronized Person1 getPerson1() {
		if(person1==null){
		person1=new Person1();
		}
		return person1;
	}
}
该方法虽然能保证多线程下正常运行,但是效率很低,因为  person1=new Person1(); 这句话在整个程序运行中只执行一次,但是所有调用getPerson1的线程都要进行同步,这样会大大减慢程序的运行效率。所以虽然该优化解决了问题但是并不好。

懒汉式 (优化二)

public class Person1 {
	private static Person1 person1 =null;
	private Person1(){
		}
	public static Person1 getPerson1() {
		if(person1==null){
			synchronized(Person1.class){
				if(person1==null)
				person1=new Person1();
			}
		}
		return person1;
	}
}
这个优化比较好的解决了多线程问题,而且效率也很好,同时也兼顾了lazy loading。

方法三加锁实现

import java.util.concurrent.locks.ReentrantLock;
public class Person1 {
	private static Person1 person1 =null;
	private static ReentrantLock lock = new ReentrantLock(false); // 创建可重入锁,false代表非公平锁  
	private Person1(){
		}
	public static Person1 getPerson1() {
		if(person1==null){
			lock.lock();
			try{
				if(person1==null)
				person1=new Person1();
			}finally{
				lock.unlock();
			}
		}
		return person1;
	}
}
该方法和 懒汉式 (优化二)非常类似

方法四 静态内部类方法实现

public class Person1 {
	private Person1(){
		}
	private static class Person1create{
		private static final Person1 person1=new Person1();
	}
	public static Person1 getPerson1() {
		return Person1create.person1;
	}
}


方法五  枚举
public enum Person1 {
	person1;
	String name=new String("ssss");
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

public class test {
	public static void main(String[] args) {
		Person1 person1 =Person1.person1;
		Person1 person2=Person1.person1 ;
		person1.setName("aaa");
		person2.setName("bbb");
		System.out.println(person1.getName()); 
		System.out.println(person2.getName()); 
	}
}
输出结果都为bbb

总结:相对来说 懒汉式 (优化二),加锁方法,静态内部类,枚举等方法是比较好的方法。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值