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

【编程素质】设计模式-单例模式(Singleton pattern)

2017-07-25 15:13 169 查看

1,概念

单例模式(单件模式Singleton pattern):

确保有一个类只有一个实例,并提供一个全局访问点。

单例设计模式是设计模式中简单且常用的一种。

2,场景

单例模式用来解决一个类在内存中只存在一个对象。即对象唯一。

如:线程池、缓存、对话框、处理偏好设置、注册表的对象、日志对象、充当打印机和显卡等设备的对象。

3,优缺点

①全局变量的替换

单件可以延迟实例化(没有全局变量的缺点)。

②保障了对象的唯一性

解决了多个实例引发的问题:如:程序的行为异常、资源使用过量、不一致的结果。无论别的类中建立了多少个Single实例,都只在内存中有的一个Single实例。

4,实现

(1)设计模式实现

提供这个实例的全局访问点,当需要实例时,通过查询单件类,返回单个实例。

①将构造函数私有化。

为了避免其它程序过多建立该类对象,先禁止其他程序建立该类对象。

②在类中创建一个本类对象。

为了其他程序可以访问到该类对象,在本类中,自定义一个对象。

③提供一个方法获取到该对象。

为了方便其他程序对自定义对象访问,可以对外提供一些访问方式。

(引用自 黑马程序员 )

2)Android中xml实现

Android中除了以上的实现方法,对于Activity的单例模式是通过在AndroidMainfest.xml中定义以下代码实现的。

android:launchMode="singleTask"


5,demo

1)懒汉式

①概念

Singleton类进内存时,对象还没有存在。对象是方法被调用时,才初始化,也叫做对象的延时调用。

利用双重检查加锁(double-checked locking)

②场景

需要外部传参才能创建对象时使用。

③实现

package Singleton;

public class Main {

public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();

s1.setName("懒汉式单件");
System.out.println(s2.getName());// 说明s1 s2指向同一个对象
}
}


package Singleton;

/**
* 懒汉式
* Singleton类进内存时,对象还没有存在。对象是方法被调用时,才初始化,也叫做对象的延时调用。
* 利用双重检查加锁(double-checked locking)
* @author luo
*/
class Singleton {
private Singleton() {
}
/**
* volatile关键词确保:当instance变量被初始化成Singleton实例时,多个线程正确地处理instance变量
*/
private volatile static Singleton instance = null;
/**
* 双重检查加锁
* 首先检查是否实例已经创建了,如果尚未创建,才进行同步区块。
* 这样只有第一次会同步。
* @return
*/
public static Singleton getInstance() {
if (null == instance) {
synchronized (Singleton.class) {
// 加锁,只有第一次才彻底执行
if (instance == null) {
//进入区块后,再检查一次,如果仍是null,才创建实例
instance = new Singleton();
}
}
}
return instance;

}

/*
* 验证
*/
private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}
}


2)饿汉式

①概念

先初始化对象。Singleton类一进内存就加载对象。

②场景

不需要外部传参使用。使用比较简单,比懒汉式常用。

③实现

package Singleton;

public class Main {

public static void main(String[] args) {

Singleton1 s11 = Singleton1.getInstance();
Singleton1 s12 = Singleton1.getInstance();

s11.setName("饿汉式单件");
System.out.println(s12.getName());// 说明s11 s12指向同一个对象
}
}


package Singleton;
/**
* 饿汉式
* 先初始化对象。Singleton类一进内存就加载对象。
* @author luo
*/
class Singleton1 {
private Singleton1() {
}
private static Singleton1 instance = new Singleton1();
public static Singleton1 getInstance() {
return instance;
}
/*
* 验证
*/
private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}
}


3)枚举单例及其他:

原来枚举也可以实现单例,这篇文章讲的很清楚:http://www.importnew.com/6461.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: