单例模式有以下的特点:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
单例模式的写法有好几种,如懒汉式单例、饿汉式单例。
一、饿汉式单例
//饿汉式单例类.在类初始化时,已经自行实例化 public class Singleton1 { private Singleton1() {} private static final Singleton1 single = new Singleton1(); //静态工厂方法 public static Singleton1 getInstance() { return single; } }
汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的
二、懒汉式单例
- 私有化构造函数。
- 声明本类引用类型变量,但是不要创建对象。
- 声明一个公共静态的方法获取本类的对象,获取之前先判断是否已经创建了本类的对象了,如果已经创建了就不要在创建直接返回即可,如果还没有创建,那么就先创建本类的引用类型变量,然后再返回。
public class Single { //私有化构造函数 private Single(){} //声明本类引用类型变量,但是不要创建对象 private static Single s; //声明一个公共静态的方法获取本类的对象 public static Single getInstance(){ if(s==null){ s=new Single(); } return s; } }
上面存在线程安全问题:
1、在getInstance方法上加同步
public static Single getInstance(){ synchronized ("lock") { if(s==null){ s=new Single(); } } return s; }
2、双重检查锁定
public static Single getInstance(){ if(s==null){ synchronized ("lock") { if(s==null){ s=new Single(); } } } return s; }