单例模式,就是一个类中只有一个实例。主要有懒汉模式和饿汉模式。
饿汉模式是在类加载的同时就创建实例,而懒汉模式是使用时才创建实例。
饿汉模式
1 2 3 4 5 6 7 8 9 10
| class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance() { return instance; } }
|
在多线程中,多个线程对同一数据进行读操作,线程安全。
懒汉模式
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Singleton{ private static Singleton1 instance = null; private Singleton1(){} public static Singleton1 getInstance() { if(instance==null){ instance = new Singleton(); } return instance; } }
|
多线程中,多个线程对同一对象进行读、写操作,线程不安全。线程不安全出现在首次创建实例时,多个线程同时调用getInstance方法,可能创造出多个实例。
改进1:
对getInstance方法加锁,保证操作的原子性,实现线程安全。
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Singleton{ private static Singleton instance = null; private Singleton1(){} public static synchronized Singleton getInstance() { if(instance==null){ instance = new Singleton(); } return instance; } }
|
但这种方法性能较差,毕竟线程不安全只出现在首次创建实例时,为getInstance方法加锁后每次都要加锁解锁,所以做如下改进。
改进2:
进入getInstance方法后首先判断instance是否为空,即是否为第一次创建实例,是才需要加锁,否则不需要加锁。同时为了避免 “内存可见性” 导致读取的 instance 出现偏差, 因此为instance加上volatile。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Singleton{ private static volatile Singleton1 instance = null; private Singleton(){} public static Singleton getInstance() { if(instance==null){ synchronized (Singleton.class){ if(instance==null){ instance = new Singleton(); } } } return instance; } }
|