单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
import java.util.HashSet; import java.util.Set; /** * @ClassName SingleInstance * @projectName: object1 * @author: Zhangmingda * @description: 单例模式,多个线程创建这个类的实例,实际只返回同一个对象 * date: 2021/4/26. */ public class SingleInstance { /** * 用一个私有变量存放自己这个类的对象 */ private static SingleInstance singleInstance = null; /** * 将构造方法私有化,避免被外面的类new出来 */ private SingleInstance() { } /** * 提供获取实例的方法 */ public static SingleInstance instance(){ String tName = Thread.currentThread().getName(); // System.out.println(tName + "获取/创建实例"); /** * 方式1:两层if判断,第一层判断不为null直接返回(快速),第二层加锁再判断一次,保证只有一个线程创建实例,其他线程二次判断不为null直接返回 */ if (singleInstance == null){ /** * 同步代码块避免多线程同时运行时,同时运行到此处并发都认为singleInstance == null,导致并发创建实例 */ System.out.println( tName+ "判断当前实例为null"); synchronized (SingleInstance.class){ if (singleInstance == null){ System.out.println(tName + "创建实例"); singleInstance = new SingleInstance(); } else { System.out.println(tName + "创建实例前二次判断,发现已有实例"); } } }else {System.out.println(tName + "第一次判断,发现已有实例");} /** * 方式二:所有创建对象的线程进来都串行判断,效率要比方式1低,因为明明有已存在实例,也得等别的线程释放锁才能返回实例 * 同步代码块避免多线程同时运行时,同时运行到此处并发都认为singleInstance == null,导致并发创建实例 */ // synchronized (SingleInstance.class){ // if (singleInstance == null){ // System.out.println(tName + "创建实例"); // singleInstance = new SingleInstance(); // }else { // System.out.println(tName + "获取到已存在实例"); // } // } return singleInstance; } public static void main(String[] args) throws InterruptedException { Runnable r = () -> { SingleInstance.instance(); }; Set<Thread> singleInstances = new HashSet<>(); for (int i=0; i<10; i++) { singleInstances.add(new Thread(r,"t"+i)); } singleInstances.forEach(thread -> thread.start()); Thread.sleep(1000); } }