单例模式及线程安全问题



一、什么是单例模式

单例模式是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种模式方法。

从概念中体现出了单例的一些特点:

(1)在任何情况下,单例类永远只有一个实例存在

(2)单例需要有能力为整个系统提供这一唯一实例 

二、单例模式之懒汉式单例

下面是实现代码:

package org.mlinge.s02;

public class MySingleton {
	
	private static MySingleton instance = null;
	
	private MySingleton(){}
	
	public static MySingleton getInstance() {
		try { 
			if(instance != null){//懒汉式 
				
			}else{
				//创建实例之前可能会有一些准备性的耗时工作 
				Thread.sleep(300);
				instance = new MySingleton();
			}
		} catch (InterruptedException e) { 
			e.printStackTrace();
		}
		return instance;
	}
}

这里假设在创建实例前有一些准备性的耗时工作要处理,多线程调用:

package org.mlinge.s02;

public class MyThread extends Thread{
  	
	@Override
	public void run() { 
		System.out.println(MySingleton.getInstance().hashCode());
	}
	
	public static void main(String[] args) { 
		
		MyThread[] mts = new MyThread[10];
		for(int i = 0 ; i < mts.length ; i++){
			mts[i] = new MyThread();
		}
		
		for (int j = 0; j < mts.length; j++) {
			mts[j].start();
		}
	}
}

执行结果如下:

1210420568
1210420568
1935123450
1718900954
1481297610
1863264879
369539795
1210420568
1210420568
602269801


从这里执行结果可以看出,单例的线程安全性并没有得到保证,那要怎么解决呢?

三、懒汉式单例之线程安全问题

同步代码块实现

package org.mlinge.s03;

public class MySingleton {
	
	private static MySingleton instance = null;
	
	private MySingleton(){}
	
	//public synchronized static MySingleton getInstance() {
	public static MySingleton getInstance() {
		try { 
			synchronized (MySingleton.class) {
				if(instance != null){//懒汉式 
					
				}else{
					//创建实例之前可能会有一些准备性的耗时工作 
					Thread.sleep(300);
					instance = new MySingleton();
				}
			}
		} catch (InterruptedException e) { 
			e.printStackTrace();
		}
		return instance;
	}
}



阅读更多

没有更多推荐了,返回首页