您的位置:首页 > 编程语言 > Java开发

浅谈Java设计模式之单例模式

2016-09-07 15:21 232 查看
什么是单例模式?

保证一个类仅有一个实例,并提供一个访问它的全局访问点.

java中的单例:一个类有且仅有一个实例,并且自行实例化向整个系统提供。

Java创建单例模式的原则

2.1 必须提供一个私有静态化的成员变量

2.2 必须提供一个私有的构造器

2.3 必须有提供一个公共的静态方法给外部访问该对象

Java创建单例模式的几种情况

3.1 饿汉模式

所谓饿汉模式就是默认把所有东西都加载好等待外界来取(该类创建的单例对象,在类加载阶段即创建)代码如下:

package com.design.singleton;
/**Java设计模式系列
* 设计模式一:单例模式之饿汉式
* @author 36963
*
*/
public class Singleton {

/*私有化构造函数,并创建一个对象,该对象为唯一的*/
private static Singleton instance = new Singleton();
private Singleton(){}
/*提供一个public的方法访问这个对象*/
public static Singleton getInstance(){
return instance;
}


这种模式,在类加载阶段就把对象创建好了,效率比较快,但是代价也比较大,会产生很多不用的对象,堆积在内存中,造成浪费。一般我们会采用lazy-reload模式,即调用 的时候创建,下一种模式

3.2 懒汉模式

所谓饱汉模式,即我想用的时候再取,不是先创建好在用。代码如下:

/**
* 懒汉式的延迟加载机制
* @author 36963
*
*/
public class Singleton3 {

private static Singleton3 instance;
private Singleton3 (){

}

public static Singleton3 getInstance(){
if(instance == null){
instance = new Singleton3();
}
return instance;
}
}


对于这种模式弥补了第一种模式的不足,但是又有新的缺陷,当进入多线程的模式下,如果两个线程都同时进入if条件语句,则有可能会产生两个不同的对象,所以,下面可以进行改进:

3.3 懒汉锁机制

学过多线程的都知道,一般防止线程并发的方法可以用synchronized关键字。ps:synchronized有多少会拼的????

代码如下:

package com.design.singleton;
/**
* 线程安全之懒汉式
* @author 36963
*
*/
public class SynchronizedSingleton {

private static SynchronizedSingleton instance;
private SynchronizedSingleton(){

}
public static synchronized SynchronizedSingleton getInstance(){
if(instance == null){
instance = new SynchronizedSingleton();
}
return instance;
}
}


显然上面的代码解决了多线程并发问题,但是出现了,效率问题,synchronized关键字加在方法上范围太大,造成等待的情况,故下面只需要减少范围即可代码如下:

package com.design.singleton;
/**
* 线程安全懒汉式改进 双重校验锁
* @author 36963
*
*/
public class Singleton4 {

// 有一种替代模式
private static Singleton4 instance;
//private static volatile Singleton4 instance;
private Singleton4(){}
public static Singleton4 getInstance(){
if(instance == null){
synchronized (Singleton4.class) {
if(instance == null){

instance = new Singleton4();
}
}
}
return instance;
}
}


对于这种模式,我们用的较多了,效率上影响不大,比较好。但是如果在Java对象序列化和反序列化中,则稍显不足,会破坏单例模式,我们给予稍稍改进即可:我们创建成员变量的时候使用voiatile声明//private static volatile Singleton4 instance;即可。

但是为了更好的体现程序猿们的编程水平可以使用下面的方式一站式解决上面的问题:使用静态内部类的方式创建,代码如下:

3.4 静态内部类的模式创建

package com.design.singleton;
/**
* 静态内部类样式
* @author 36963
*
*/
public class StaticInnerSingleton {

private static class SingletonHolder{
private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
}

private StaticInnerSingleton(){

}

public static final StaticInnerSingleton getInstance(){
return SingletonHolder.INSTANCE;
}
}


这种方式可以解决以上几种问题。非常常用,,,

以上是我对单例模式的简单理解。。。模式系列未完待续。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: