• Easy单例模式


    在学习单例模式前,不妨问自己几个问题:单例模式是怎么来的,单例模式怎么去用?

    单例模式是怎么来的?

    这就从设计模式起源开始,他是在实际实践中遇到类似情况可以通用经验所得到的总结,一般在其他模块或者方法多次调用类对象,也就是公共模块,用单例模式可以减少内存的消耗。

    单例模式怎么去用?

    那这个容易,然后很快不到一分钟写完了。

     1 public class singleTonEx01 {
     2 
     3     private static singleTonEx01 singleTon;
     4 
     5     public static void main(String args[]) {
     6         singleTonEx01 test1=singleTonEx01.getInstance();
     7         test1.CommonMethod();
     8     }
     9 
    10     // 防止使用new构造函数实例化对象
    11     private singleTonEx01() {
    12 
    13     }
    14 
    15     public static singleTonEx01 getInstance() {
    16         if(null==singleTon)
    17             singleTon=new singleTonEx01();
    18         return singleTon;
    19     }
    20     
    21     public void CommonMethod() {
    22         System.out.println(getClass().getName());
    23     }
    24 
    25 }
    View Code

    但这里会有问题,啥问题呢?单线程中是没问题,但是多线程会出现问题,假设两个多线程A与B,A与B同时判断singleTon不为空,那会创建两次,那对于这个问题需要使用同步锁去解决了,下面改造下代码。

    public class singleTonEx01 {
    
        private static singleTonEx01 singleTon;
    
        public static void main(String args[]) {
            singleTonEx01 test1 = singleTonEx01.getInstance();
            test1.CommonMethod();
        }
    
        // 防止使用new构造函数实例化对象
        private singleTonEx01() {
    
        }
    
        public static singleTonEx01 getInstance() {
            synchronized (singleTonEx01.class) {
                if (null == singleTon)
                    singleTon = new singleTonEx01();
            }
            return singleTon;
        }
    
        public void CommonMethod() {
            System.out.println(getClass().getName());
        }
    
    }
    View Code

    这还不是最好的方法,如果是这样的话每个线程都会使用同步锁代码块,使用同步锁其实是消耗资源的,因此,可以再改进下,在外面锁再加个判断,这样一来提高了效率。(推荐这种写法1)

    另外,补充一下,实例变量加上volatile的意义。

    创建对象可以分解为如下的3行伪代码memory=allocate(); //1:分配对象的内存空间ctorInstance(memory); //2:初始化对象instance=memory; //3:设置instance指向刚分配的内存地址上面3行代码中的2和3之间,可能会被重排序导致先3后2;

    public class singleTonEx01 {
    
        private volatile static singleTonEx01 singleTon;
    
        public static void main(String args[]) {
            singleTonEx01 test1 = singleTonEx01.getInstance();
            test1.CommonMethod();
        }
    
        // 防止使用new构造函数实例化对象
        private singleTonEx01() {
    
        }
    
        public static singleTonEx01 getInstance() {
            if (singleTon == null) {
                synchronized (singleTonEx01.class) {
                    if (null == singleTon)
                        singleTon = new singleTonEx01();
                }
            }
            return singleTon;
        }
    
        public void CommonMethod() {
            System.out.println(getClass().getName());
        }
    
    }
    View Code

    其实还有另外两种方法,一种是不管有没有调用都实例化(俗称恶汉式),另一种是静态内部类的方法(推荐这种写法2),线程安全而且高效

    public class singleTonEx02 {
    
        private   static final singleTonEx02 singleTon=new singleTonEx02();
    
        public static void main(String args[]) {
            singleTonEx02 test1 = singleTon;
            test1.CommonMethod();
        }
    
        // 防止使用new构造函数实例化对象
        private singleTonEx02() {
    
        }
        
        public static singleTonEx02 getIntance() {
            return singleTon;
        }
    
         
        public void CommonMethod() {
            System.out.println(getClass().getName());
        }
    
    }
    View Code
    public class singleTonEx03 {
    
        private static class SingleNBClass {
    
            private final static singleTonEx03 singleTonEx03=new singleTonEx03();
            
        }
    
        public static void main(String args[]) {
            singleTonEx03 test1 = singleTonEx03.getIntance();
            test1.CommonMethod();
        }
    
        // 防止使用new构造函数实例化对象
        private singleTonEx03() {
    
        }
    
        public static final singleTonEx03 getIntance() {
            return SingleNBClass.singleTonEx03;
        }
    
        public void CommonMethod() {
            System.out.println(getClass().getName());
        }
    
    }
    View Code
  • 相关阅读:
    Wpf 数据绑定实例2
    Wpf 数据绑定简介、实例1
    Wpf ListBox数据绑定实例1--绑定字典集合
    Wpf控件ListBox使用实例2
    阿里UX矢量图标库–最强大的矢量图标库(Icon font制作力荐工具)
    Web字体工具整理,网页图标字体以及使用方法整理
    ICOMOON!强悍的WEB字体图标制造器/Web字体使用实例
    window.applicationCache事件,介绍
    HTML5 离线缓存忽略主页实例
    条件注释判断浏览器版本<!--[if lt IE 9]>(转载)
  • 原文地址:https://www.cnblogs.com/lmf-techniques/p/6400382.html
Copyright © 2020-2023  润新知