编程语言 php java

java设计模式之单例模式

java HTML我帮您 1年前  0次浏览
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
  单例模式有一下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。
  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

这样的模式有几个好处:
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。

首先我们写一个简单的单例类:
public class Singleton {  

/* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
private static Singleton instance = null;

/* 私有构造方法,防止被实例化 */
private Singleton() {
}

/* 静态工程方法,创建实例 */
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}

// Other methods...
}
现在给大家列举几种我知道的单例模式
1.饿汉式单例类
//饿汉式单例类.在类初始化时,已经自行实例化 
class S1 {
//私有的默认构造子
private S1() {
System.out.println("ok1");
}
//已经自行实例化
private static S1 instance = new S1();

//静态工厂方法
public static S1 getInstance() {
return instance;
}
}
优点:

1.线程安全的

2.在类加载的同时已经创建好一个静态对象,调用时反应速度快。

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

//懒汉式单例类.在第一次调用的时候实例化 
class S2 {
//私有的默认构造子
private S2() {}
//注意,这里没有final
private static S2 single=null;
//静态工厂方法
public static S2 getInstance() {
if (single == null) {
single = new S2();
}
return single;
}
}
优点:1.线程安全的,
2.在类加载的同时已经创建好一个静态对象,调用时反应速度快。

缺点: 资源利用效率不高,可能这个单例不会需要使用也被系统加载
public synchronized  static S2 getInstance() {
if (single == null) {
single = new S2();
}
return single;
}
优点:1.资源利用率高
缺点:第一次加载是发应不快 ,多线程使用不必要的同步开销大
public static S2 getInstance() {  
if (single == null) {
synchronized (single) {
if (single == null) {
single = new S2();
}
}
}
return single;
}
优点:1.资源利用率高
缺点:第一次加载是发应不快 ,由于java 内存模型一些原因偶尔会失败
登记式单例类
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。
class S3 {
private static Map map = new HashMap();
static{
S3 single = new S3();
map.put(single.getClass().getName(), single);
}
//保护的默认构造子
protected S3(){}
//静态工厂方法,返还此类惟一的实例
public static S3 getInstance(String name) {
if(name == null) {
name = S3.class.getName();
System.out.println("name == null"+"-name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (S3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
}

class S3Child extends S3{
public S3Child(){

}
/**
* 静态工厂方法
*/
public static S3Child getInstance() {
return (S3Child) S3.getInstance("com.html580.singleton.S3Child");
}

/**
* 一个示意性的商业方法
*/
public String about() {
return "Hello, I am RegSingletonChild.";
}

public static void main(String<> args) {
S3Child single3 = S3Child.getInstance();
System.out.println(single3.about());
}
}

















发表评论