首页 > 程序开发 > 综合编程 > 安全编程 > 正文
单例模式之线程安全
2017-06-15 09:27:00       个评论    来源:花满溪的博客  
收藏    我要投稿

单例模式之线程安全,关于饿汉模式与懒汉模式的线程安全问题:

1、饿汉模式:即静态初始化的方式,它是类一加载就实例化对象,所以要提前占用系统资源,因此线程安全

2、懒汉模式:在多线程的程序中,多个线程同时调用单例类中的getInstance()方法时,会有可能造成创建多个实例,所以懒汉模式 线程不安全

下面讨论懒汉模式中的线程安全问题:

1、不使用同步锁(即使用饿汉模式)

/**
 * @author huamanxi
 * 使用饿汉模式
 */
public class Singleton {
	/*
	 * 1.让构造方法私有化,不允许外部直接创建对象
	 * 私有化后外界不能访问,步骤2解决外界不能访问的问题
	 */
	private Singleton(){
		
	}
	/*
	 * 2.使用private static修饰获取的对象,外界无法访问
	 */
	private static Singleton instance=new Singleton();
	
	/*
	 * 3.提供一个用于获取实例的静态方法  
	 * 使用public static修饰获取对象的方法
	 */
	public static Singleton getInstance(){
		return instance;
	}
}

这种方式的缺点是该类加载的时候就会直接new一个静态对象,但系统中这样的类较多时,会使得启动速度变慢。现在流行的设计

是“延迟加载”,我们可以在第一次使用的时候才初始化第一个该类对象。所以这种适合在小系统。

2、使用同步方法

/**
 * @author huamanxi
 * 使用同步方法
 */
public class Singleton {
	private void Sigleton() {
		
	} 
	
	private static Singleton instance;
	
	//对获取实例的方法进行同步
	public static synchronized Singleton getInstance(){
		if(instance==null){
			instance=new Singleton();
		}
		return instance;
	}
}
这种方法一次性锁住了一个方法,这个粒度有点大,这样每次调用getInstance()方法时都需要lock,会影响性能,下面对这个类进行改良,锁住new语句就可以了(就是“双重锁”机制)

3、使用双重同步锁

/**
 * @author huamanxi
 * 使用双重同步锁机制
 */
public class Singleton {
	private void Sigleton() {
		
	} 
	
	private static Singleton instance;
	
	//对获取实例的方法进行同步
	public static Singleton getInstance(){
		if(instance==null){
			
			//对获取实例的方法进行同步
			synchronized (Singleton.class) {
				if(instance==null){
					instance=new Singleton();
				}
			}
			
		}
		return instance;
	}
}
对于双重锁定方法,已经在外面判断了instance实例是否存在,为什么在lock里面还要做一次instance实例是否存在的判断呢?

原因:对于instance存在的情况,就直接返回,这没有问题。

当instance为null并且同时有两个线程调用getInstance()方法时,它们将都可以通过第一重instance==null判断。然后由于同步机制,这两个线程只有一个进入,另一个在外排队等候,必须要期中一个进入并出来后,另一个才能进入。而此时如果没有了第二重的instance==null的判断,则第一个线程创建了实例,而第二个线程还是可以继续再创建新的实例,这就不能达到单例的目的。

点击复制链接 与好友分享!回本站首页
上一篇:如何使用Python获取文件所在目录和文件名
下一篇:线程安全与可重入函数
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做实用的IT技术学习网站