zoukankan      html  css  js  c++  java
  • java 多线程,单例模式类(创建对象)最优写法

    单例模式

    单例模式(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);
        }
    }

  • 相关阅读:
    x8086汇编在显存中显示字符串
    x8086汇编实现dos清屏(clear screen)
    原创:根据题目要求,通过素数的方式判断一个小的字符串是否属于另一个大的字符串的子集
    python signal信号
    转:python signal信号
    python signal(信号)
    python问题记录
    Python语言and-or的用法
    perl6中的q/qq/qx/qqx
    upupw注入by pass
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/14704174.html
Copyright © 2011-2022 走看看