保证一个类只有一个实例
在单线程环境下 实例只有一个
class SingletonTest{ public static void main(String[] args) { Singleton singleton1 = Singleton.getInstance(); Singleton singleton2 = Singleton.getInstance(); // 都是同一个实例 System.out.println(singleton1 == singleton2); } } public class Singleton { public static Singleton singleton; // 私有化构造方法 private Singleton(){}; // 调用该方法的时候才实例化 public static Singleton getInstance(){ if(singleton == null){ singleton = new Singleton(); } return singleton; } }
在多线程的环境下 会创建多个实例
public static void main(String[] args) { new Thread(()->{ Singleton instance = Singleton.getInstance(); System.out.println(instance); }).start(); new Thread(()->{ Singleton instance = Singleton.getInstance(); System.out.println(instance); }).start(); }
// 加锁 public synchronized static Singleton getInstance(){ if(singleton == null){ singleton = new Singleton(); } return singleton; }
因为在多线程 并发访问 if(singleton == null) 的时候 会造成线程不安全问题 导致创建2个不同的实例
解决方法:
如果加 synchronized 程序会有性能的损耗 每次有线程访问 getInstance 方法的时候 都需要进行加锁操作
public static Singleton getInstance(){ // 如果singleton等于空的时候 是不需要加锁的 if(singleton == null){ synchronized (Singleton.class){ singleton = new Singleton(); } } return singleton; }
还是会创建两个不同的实例 假如说第一个线程返回实例 第二个线程排队等待 等第一个线程释放锁的时候 第二个线程还是会创建一个新的对象
// 防止 使用到未初始化的实例和指令重排 public volatile static Singleton singleton; // 私有化构造方法 private Singleton(){}; // 调用该方法的时候才实例化 public static Singleton getInstance(){ // 如果singleton等于空的时候 是不需要加锁的 if(singleton == null){ synchronized (Singleton.class){ // 多加一次判断 if(singleton == null){ singleton = new Singleton(); } } } return singleton; }
只实例化了一个对象
class InnerSingletonTest{ public static void main(String[] args) { InnerSingleton instance1 = InnerSingleton.getInstance(); InnerSingleton instance2 = InnerSingleton.getInstance(); System.out.println(instance1 == instance2); new Thread(()->{ InnerSingleton instance = InnerSingleton.getInstance(); System.out.println(instance); }).start(); new Thread(()->{ InnerSingleton instance = InnerSingleton.getInstance(); System.out.println(instance); }).start(); } } public class InnerSingleton { // 需要的时候 才实例话 private static class InnerSingletonOne{ private static InnerSingleton innerSingleton = new InnerSingleton(); } private InnerSingleton(){ } public static InnerSingleton getInstance(){ return InnerSingletonOne.innerSingleton; } }
只有一个实例
class HungryTest{ public static void main(String[] args) { } } public class Hungry { // 类初始化的时候就创建了 private static Hungry hungry = new Hungry(); private Hungry(){}; public Hungry getHungry(){ return hungry; }
原文:https://www.cnblogs.com/chenziyue/p/12512304.html