常用单例模式详解
Posted Crystal的加糖日记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用单例模式详解相关的知识,希望对你有一定的参考价值。
单例模式概念:
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
注意:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
下面介绍两种常用的单例模式:饿汉式,懒汉式
饿汉式:
//饿汉式:创建对象实例的时候就直接初始化操作 空间换时间
public class Single {
//1.创建类中的私有构造
private Single() {}
//2.创建该类型的私有静态实例
private static Single instance=new Single();
//3.创建公有静态方法返回静态实例对象
public static Single getInstance() {
return instance;
}
}
Single one=Single.getInstance();
//在测试类中,静态方法,通过类名调用
线程安全性:饿汉式是在加载的时候就进行了对象的实例化创建,所以即使多个线程一起进行,访问的实例对象也唯一,所以线程安全。
懒汉式:
//懒汉式:类内实例对象创建时并不直接初始化,直到
//第一次调用get方法时,才完成初始化操作 时间换空间
public class SingleTon {
//创建私有构造方法
private SingleTon() { }
//创建你静态的该类实例对象
private static SingleTon instance=null;
//创建开放的静态方法提供实例对象
public static SingleTon getInstance() {
if(instance==null)
instance=new SingleTon();
return instance;
}
}
SingleTon one1=SingleTon.getInstance();
//在测试类中,静态方法,通过类名调用
线程安全性:可以看出,但是以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有下面三种方式,可以对getInstance这个方法改造,为了保证懒汉式单例的线程安全。
第一种方式:
public class SingleTon3 {
//创建私有构造方法
private SingleTon3() {}
//创建你静态的该类实例对象
private static SingleTon3 instance=null;
//创建开放的静态方法提供实例对象
//在getInstance方法上加同步synchronized
public static synchronized SingleTon3 getInstance() {
if(instance==null)
instance=new SingleTon3();
return instance;
}
}
第二种方式:
public class SingleTon2 {
//创建私有构造方法
private SingleTon2() {}
//创建你静态的该类实例对象
private static SingleTon2 instance=null;
//双重检查锁定
public static SingleTon2 getInstance() {
if (instance == null) {
synchronized (SingleTon2.class) {
if (instance == null) {
instance = new SingleTon2();
}
}
}
return instance;
}
}
第三种方式:
public class SingleTon4 {
//静态内部类
private static class InnerObject{
private static final SingleTon4 instance = new SingleTon4();
}
private SingleTon4 (){}
public static final SingleTon4 getInstance() {
return InnerObject.instance;
}
}
这三种实现在资源加载和性能方面有些区别:
第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能。
第2种,在getInstance中做了两次null检查,可以避免整个方法被锁,只对需要锁的代码部分加锁,可以提高执行效率。
第3种,静态内部类虽然保证了单例在多线程并发下的线程安全性,但刅序列化对象时候,默认的方式运行得到的结果是多例的。
好啦,今天的单例模式学习就到这儿啦~你有收获吗?
一起学习吧~
以上是关于常用单例模式详解的主要内容,如果未能解决你的问题,请参考以下文章