java设计模式---------单利模式

**单利模式:**确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全 局访问的方法。单例模式是一种对象创建型模式。
三个要点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
使用方法:
在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。

(1)懒汉单利模式:
线程不安全,多线程下会创建两个对象; 在第一个线程进来后,还未将地址值赋值给mySigleTon,第一线程结束,
第二线程仍然可以进来创建了两个对象;

class MySigleTon {
    private static MySigleTon sigleTon = null;   //  定义一个类的引用,指向null;
    private MySigleTon() {					//  构造方法
        System.out.println("MySigleTon().init");
    }
   //提供一个全局的访问点
    public static MySigleTon getInstance() {
       if(sigleTon == null) {				//  如果引用为null,说明没有实例对象此时可以去建立一个
            sigleTon = new MySigleTon();
     	   }
        return sigleTon;
   	 }
 }

(2)懒汉单利模式的几种变种以及存在的问题:

class MySigleTon {
    private static MySigleTon mySigleTon = null;  // 先定义一个引用,
   private MySigleTon() {
        System.out.println(".000000");
    }
    // 提供一个全局访问点
    public static MySigleTon getInstance() {
**第一种:**

          //在多线程下仍需要将竞态条件至少执行两边
        /*  第一个线程进入,未将地址值赋给对象引用,
            第二个线程已进入if语句,待解锁之后,进入锁依然创建第二个对象;
         */
        if (mySigleTon==null) {
            synchronized (lock) {
                mySigleTon=new MySigleTon();   //创建对象
            }
        }
**第二种:**

        //    在单线程下效率不高,反复进锁出锁(得进锁之后才能知道不能创建新的对象)
        synchronized (lock) {
            if (mySigleTon==null) {
                mySigleTon=new MySigleTon();
            }
        }
        
   **第三种:**     
   
        //  多线程下会创建两个对象;
        /*
         在第一个线程进来后,还未将地址值赋值给mySigleTon,第一线程结束,第二线程仍然可以进来
         创建了两个对象
        */
        if (mySigleTon==null) {
            mySigleTon=new MySigleTon();
        }
        
        return mySigleTon;      //返回唯一的一个对象
    }
}

(3) 饿汉单利模式:

// 饿汉式单例模式
class MySigleTon2 {
    private static MySigleTon2 mySigleTon2 = new MySigleTon2(); // 首先只能初始化一次,创建一个(唯一的)对象  static修饰,
    public MySigleTon2() {
        System.out.println("0000002");
    }
    //提供一个全局的访问点
    public  static MySigleTon2 getInstance() {  
        return mySigleTon2;
    }
}

(4) 静态内部类实现单利模式:

// 因为静态内部类课以定义静态变量和方法
class MySingleTon3{
    private MySingleTon3(){
        System.out.println("静态内部类的单利模式");
    }
		//  只有访问静态内部类才会创建对象 
    private  static class SignleTon {
        public  static MySingleTon3 mySingleTon3=new MySingleTon3();   
    }
    public static MySingleTon3 getMySingleTon3() { 
        return SignleTon.mySingleTon3;
    }
}

(5)双重校验锁

class MySigleTon {
    private static MySigleTon mySigleTon = null;  // 先定义一个引用,
    private static Object lock = new Object(); //  lock 锁;创建了一个锁的对象;

    private MySigleTon() {
        System.out.println(".000000");
    }
    // 提供一个全局访问点
    public static MySigleTon getInstance() {
        // 双重锁,可以防止创建两次对象   多线程和单线程下都可用
        if (mySigleTon == null) {   //      如果为null,则线程进入等待当前锁执行完进入锁
            synchronized (lock) {    //           synchrnized 线程保护关键字
                if (mySigleTon==null) {      //     第二线程进入,判断是指向null,
                    mySigleTon = new MySigleTon();  //       》》》竞态条件  创建一个唯一的对象
                }
            }
        }
        return mySigleTon;
 }

(5)枚举实现单利模式:

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
} 

你可能感兴趣的:(设计模式,单利模式,懒汉单利模式,饿汉单利模式)