zoukankan      html  css  js  c++  java
  • Java设计模式の单利模式

      单利模式:确保一个类最多只有一个实例,并提供一个全局访问点

      经典单利模式创建对象代码  

    public class Singleton {
        private static Singleton uniqueInstance = null;
        private Singleton(){
            
        }
        public static Singleton getInstance(){
            if (uniqueInstance==null) {
                uniqueInstance=new Singleton();
            }
            return uniqueInstance;
        }
    }

      问题:多线程

    public class Q {
        //多线程
        private static Q uniqueInstance = null;
        private Q(){
            
        }
        public static Q getInstance(){
            if (uniqueInstance==null) {//当线程1执行此语句后,判断通过,
                /*正准备执行uniqueInstance=new Q()时,线程2抢占到了cpu资源,
                 *切换到线程2开始执行,线程2会发现uniqueInstance还是null,所以会创建对象,创建完后,
                 *而当切换到线程1时,发现线程1已经进入if判断,所以也会创建一个新uniqueInstance,
                 *此时线程1创建的uniqueInstance和线程2创建的uniqueInstanc是不一样的
                 **/
                uniqueInstance=new Q();
            }
            return uniqueInstance;
        }
    }

      解决办法

      1、创建对象的方法加同步锁

    /**
     * 优化方式1
     * 方法添加同步锁
     * 优点:使用方便
     * 缺点:当线程很多的情况下,非常耗费资源
     * @author yxm
     *
     */
    public class Optimization_Singleton_1 {
        private static Optimization_Singleton_1 uniqueInstance = null;
        private Optimization_Singleton_1(){
            
        }
        public synchronized static Optimization_Singleton_1 getInstance(){
            if (uniqueInstance==null) {
                uniqueInstance=new Optimization_Singleton_1();
            }
            return uniqueInstance;
        }
    }

      2、饿汉式创建对象

    /**
     * 优化方式2
     * 急切创建对象
     * 优点:不会因为加锁而耗费资源
     * 缺点:当不使用此类时,照样会耗费内存
     * @author yxm
     *
     */
    public class Optimization_Singleton_2 {
        private static Optimization_Singleton_2 uniqueInstance = new Optimization_Singleton_2();
        private Optimization_Singleton_2(){
            
        }
        public static Optimization_Singleton_2 getInstance(){
            if (uniqueInstance==null) {
                uniqueInstance=new Optimization_Singleton_2();
            }
            return uniqueInstance;
        }
    }

      3、双重检查加锁 (较完美)

    /**
     * 优化方式3
     * 双重检查加锁
     * 较完美
     * @author yxm
     *
     */
    public class Optimization_Singleton_3 {
        private volatile static Optimization_Singleton_3 uniqueInstance = null;//volatile给编译器使用,保证线程安全
        private Optimization_Singleton_3(){
            
        }
        public synchronized static Optimization_Singleton_3 getInstance(){
            if (uniqueInstance==null) {
           //只有等线程1把对象创建好了,其他线程才会进入以下代码块
    synchronized(Optimization_Singleton_3.class){ if (uniqueInstance==null) { uniqueInstance=new Optimization_Singleton_3(); } } } return uniqueInstance; } }

      案例:一个巧克力工厂,生产各式各样的巧克力,生产过程有(准备原料、填充、加热、排出)四道工序,但是现在工厂里只有一条生产线,意味着一次只能生产一种巧克力,请问如何把控?

      分析:转换为计算机思维,此场景是典型的一个类只能有一个对象,符合单利模式特征

      普通巧克力工厂

    public class ChocolateFactory {
        private boolean empty;
        private boolean boiled;
        
        public ChocolateFactory(){
            empty=true;
            boiled=false;
        }
        //填充
        public void fill(){
            if (empty) {
                empty=false;
                boiled=false;
            }
        }
        //加热
        public void boil(){
            if (!boiled) {
                boiled=true;
            }
        }
        //排出
        public void drain(){
            if (!empty&&boiled) {
                empty=true;
            }
        }
    }

      使用单利模式后的巧克力工厂

    public class ChocolateFactoryInSingleton {
        private boolean empty;
        private boolean boiled;
        public static ChocolateFactoryInSingleton uniqueInstance=null;
        private ChocolateFactoryInSingleton(){
            empty=true;
            boiled=false;
        }
        public static ChocolateFactoryInSingleton getInstance(){
         //此处确保不同的巧克力不会进入同一条生产线
    if (uniqueInstance==null) { uniqueInstance=new ChocolateFactoryInSingleton(); } return uniqueInstance; } //填充 public void fill(){ if (empty) { empty=false; boiled=false; } } //加热 public void boil(){ if (!boiled) { boiled=true; } } //排出 public void drain(){ if (!empty&&boiled) { empty=true; } } }
  • 相关阅读:
    使用iScroll时,input等不能输入内容的解决方法
    用jquery 写的类似微博发布的效果
    jq 中each的用法 (share)
    Android SDK 安装中组件的离线安装方法 (share)
    HTML5开发手机应用viewport的作用
    Android开发环境搭建及配置phoneGap
    flipsnap手机屏幕水平滑动框架
    解读网站PR值
    文档碎片
    解读SEO 黑帽白帽 (share)
  • 原文地址:https://www.cnblogs.com/tomcatx/p/4640707.html
Copyright © 2011-2022 走看看