单例模式

2018-08-08  本文已影响0人  海是倒过来的天_67f2

单利模式的核心结构中包含一个被称为单利的特殊类,通过单例模式可以保证系统中,应用该模式的 类只有一个实例对象。

1.单利模式的优缺点;

优点:系统中该类的对象的实例只有一个,节省了系统资源,对于一些需要频繁创建和销毁的对象,使用单利模式可以提高系统性能。

缺点:要想实例化单例时,必须要记住获取对象的方法,而不是使用new方法,可能会给开发者带来困扰

2.适用场所:

需要频繁的创建和销毁对象

创建对象时耗时过多或消耗资源过多,又经常使用到的对象。

工具栏对象

频繁访问数据库或者文件的对象。

3.单利模式分为两种懒汉模式和恶汉模式

懒汉模式:在类初始化的时候不进行初始化

恶汉模式:在类加载完的时候就完成了初始化,所有类一块加载,加载速度较慢,但是获取对象速度较快。

1.恶汉模式(静态常量)

public class SingleMode{

private final static SingleMode INSTANCE = new SingleMode();

private SingleMode(){}

public static  SingleMode getInstance(){

return INSTANCE;

}

}

优点:写法比较简单,在类加载的时候就完成了创建,避免了线程同步的问题

缺点:在类加载的时候就完成了创建,没有达到懒加载的目的,如果至始至终没有使用过这个实例,会造成资源浪费。

2恶汉模式(静态代码块)

public class SingleMode{

private static SingleMode sInstance;

static {

sInstance = new SingleMode()

}

public static SingleMode getInstance(){

return sInstance;

}

}

几乎和方法1一样,只不过是将实例化的过程放在了静态代码块中,也是在类加载的时候就执行了静态代码块中的数据,优缺点和方法1一样。

3.懒汉模式(线程不安全)

public class SingleMode(){

private static SingleMode instance;

private SingleMode(){}

public static  SingleMode getInstance(){

if(instace == null){

instance = new SingleMode;

}

return instance;

}

}

一般只在单线程中使用,如果在多线程中使用可能会产生多个实例,因此不采用。

4.懒汉模式(线程安全)

public class SingleMode{

private SingleMode instance;

private SingleMode(){}

public static synchronized SingleMode getInstance(){

if(instance == null){

instance = new Singlemode();

}

return instance;

}

}

解决了线程不安全的问题,但是每个线程想要获得类的实例时,都需要调用getInstance()方法进行同步,效率太低。

5.懒汉模式(线程安全,同步代码块,不在同步整个方法)

public class SingleMode{

private SingleMode sInstance;

private SingleMode(){}

public static SingleMode getInstance(){

if(sInstance == null){

synchronized(this){

sInstance = new SingleMode();

}

}

return sInstance;

}

}

这种方式看是方法四的优化,其实不然,这种方式和第三种一样,并不能保证线程安全,例如一个线程进入了if(sInstance == null)判断语句,还未来得及创建实例,此时另外一个线程也通过了这个判断语句,此时就会产生多个实例。

6.懒汉模式双重检查(线程安全)

public class SingleMode{

private static SingleMode sInstance;

private SingleMode(){}

public static SingleMode getInstance(){

if(sInstance == null){

synchronized(this){

if(sInstance == null){

sInstance = new SingleMode();

}

}

}

return sInstance;

}

}

双重检查在多线程中很常见,在代码中,进行了两次if(sInstance == null)的检查,这样就可以保证了线程安全

优点:线程安全,延迟加载,效率较高

7.静态内部类

public class SingleMode{

private SingleMode(){}

private static class SingleHolder{

private static final SingleMode INSTANCE = new SingleMode();

}

public static SingleMode getInstance(){

reruen  SingleHolder.INSTANCE;

}

}

静态内部类的实现方式和恶汉模式采用的机制类似,但是又有所不同,两者都采用了类加载的机制来保证初始化时,只有一个线程。不同的地方在于恶汉模式只要SingleMode类被加载就会初始化,没有懒加载的作用,而静态内部类在SingleMode类被加载时不会立即实例化。而是在需要实例化的时候才会调用getInstance,从而加载SingleHolder类,完成SingleMode的实例化。

优点,避免了线程不安全,延迟加载,效率高

8.枚举

public enum SingleMode{

INSTANCE;

public void whateverMethod(){

}

}

JDK1.5以后才出现的单例模式,不仅能避免多线程问题而且还能防止反序列化重新创建新的对象。项目中很少用到。

上一篇 下一篇

猜你喜欢

热点阅读