zoukankan      html  css  js  c++  java
  • 设计模式整理_单例设计模式

      单例设计模式,它确保一个类只有一个实例,并提供一个全局访问点.

      由于单例设计模式对应的类只能创建一个对象,因此它所对应的方法必须是static(不是static只有创建对象才能调用).

      以下是单例模式的一个经典实现:采用了延迟加载对象的例子.

      

    public class Single1 {
        private static Single1 single;    //利用一个静态变量来记录Single1的唯一实例,这里没有直接声明,采用了延迟加载模式.
        private Single1(){}                //把构造器声明为私有的,只有在Single1类内才可以调用构造器.
        public static Single1 getInstance() {    
            if(single==null) {
                single=new Single1();        //利用getInstance方法实例化对象.
            }
            return single;
        }
        //其他方法.Single1作为一个正常的类,应该是有其他方法的.
    }

      但是上述实现有个重要的缺点,在多线程环境下是可能产生两个对象的.例如如下代码:

    public class Test {
        public static void main(String[] args) {
            Thread t1=new Thread(){
                public void run() {
                    for(int i=0;i<2;i++) {
                        System.out.println(Thread.currentThread().getName()+Single1.getInstance());
                    }
                }
            };
            Thread t2=new Thread(){
                public void run() {
                    for(int i=0;i<2;i++) {
                        System.out.println(Thread.currentThread().getName()+Single1.getInstance());
                    }
                }
            };
            t1.start();
            t2.start();
        }
    }

    将产生如下的输出:

    Thread-1five.Single1@459189e1
    Thread-0five.Single1@55f33675
    Thread-1five.Single1@55f33675
    Thread-0five.Single1@55f33675

      可以看出,已经产生了两个对象,这是因为getInstance方法,没有同步的缘故,但是如果直接在方法上增加了同步的话,势必会造成每次获取对象都要获得锁造成效率降低,因此最好的方法是在第一次获取对象的时候,采用同步,具体的做法见如下代码:

    public class Single1 {
        private volatile static Single1 single;    //在两个或多个线程访问的成员变量上采用volatile关键字.确保多个线程正确处理变量
        private Single1(){}                
        public static Single1 getInstance() {    
            if(single==null) {
                synchronized(Single1.class) /*只有第一次才彻底执行这里的代码.*/{
                    if(single==null)    //进入区域后再检查一次,如果仍是null,才检查实例.
                    single=new Single1();        
                }
            }
            return single;
        }
    }

      在对于对资源要求不苛刻的情况下,可以采用直接加载的方式,这时候就不需要加同步了.

    public class Single1 {
        private  static Single1 single=new Single1();    
        private Single1(){}                
        public static Single1 getInstance() {    
            return single;
        }
    }
  • 相关阅读:
    ZOJ 2770 Burn the Linked Camp 差分约束
    作业04 一个简单的扑克牌游戏
    C++友元
    ZOJ 3645高斯消元
    CodeForces 55D 数位统计
    03类的设计和使用
    HDU 4522
    POJ 2559单调栈
    PL/SQL REPORT 开发模拟登陆
    修改报表心得
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5597162.html
Copyright © 2011-2022 走看看