jtahstu的博客

1373758426   root@jtahstu.com   Git仓库   英文博客  

最新碎语:以后没事写写小的知识点吧

您的位置:jtahstu的博客 >笔记> 设计模式从入门到放弃 - 单例模式

设计模式从入门到放弃 - 单例模式

单例模式定义:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,他提供全局访问的方法。

单例模式的要点有三个:

一是某个类只能有一个实例;

二是它必须自行创建这个实例;

三是它必须自行向整个系统提供这个实例。

单例模式是一种对象创建型模式。

单例uml图

饿汉式单例

public class Singleton {
	private static Singleton instance = new Singleton();

	private Singleton() {
	}

	public static Singleton getInstance() {
		return instance;
	}
}
饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

懒汉式单例

package Singleton;

public class Singleton {
	private static Singleton instance = null;

	private Singleton() {
	}

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

以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全

1、在getInstance方法上加同步

public static synchronized Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
} 

2、双重检查锁定

    public static Singleton getInstance() {  
            if (singleton == null) {    
                synchronized (Singleton.class) {    
                   if (singleton == null) {    
                      singleton = new Singleton();   
                   }    
                }    
            }    
            return singleton;   
        }  
3、静态内部类
public class Singleton {    
    private static class LazyHolder {    
       private static final Singleton INSTANCE = new Singleton();    
    }    
    private Singleton (){}    
    public static final Singleton getInstance() {    
       return LazyHolder.INSTANCE;    
    }    
}  

什么是线程安全?

        如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。

PHP代码

<?php

/**
 * Created by PhpStorm.
 * User: jtahstu
 * Date: 2016/8/24
 * Time: 12:09
 */
class test {
	private static $_instance;
	//保存类实例的私有静态成员变量

	//定义一个私有的构造函数,确保单例类不能通过new关键字实例化,只能被其自身实例化
	private final function __construct() {
		echo 'test __construct';
	}

	//定义私有的__clone()方法,确保单例类不能被复制或克隆
	private function __clone() {
	}

	public static function getInstance() {
		//检测类是否被实例化
		if (!(self::$_instance instanceof self)) {
			self::$_instance = new test();
		}
		return self::$_instance;
	}

}

//调用单例类
test::getInstance();

C#利用静态构造函数的方式实现


public sealed class Singleton{
	private Singleton(){

	}

	private static Singleton instance=new Singleton();

	public static Singleton Instance{
		get{
			return instance;
		}
	}
}


总结一下单例类需要注意的几点:

一、单例模式是用来实现在整个程序中只有一个实例的。

二、单例类的构造函数必须为私有,同时单例类必须提供一个全局访问点。

三、单例模式在多线程下的同步问题和性能问题的解决。

四、懒汉式和饿汉式单例类。


---

本文章采用 知识共享署名2.5中国大陆许可协议 进行许可,欢迎转载,演绎或用于商业目的。

---

二维码加载中...

扫一扫移动端访问O(∩_∩)O

发表评论

17 + 71 =
路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交
正在加载中……