2020年9月15日 单利设计模式(面试题)

package com.atguigu.test17;

import org.junit.Test;

/*
 * 单例设计模式:
 * 
 * 单例:某个类只能有唯一的一个实例对象。
 * 
 * 如何实现单例?
 * 1、饿/恶汉式
 * 不管我们使用者是否需要这个对象,它都上来先给你创建好这个唯一的对象。
 * (1)枚举类型
 * (2)形式二
 * ①构造器私有化
 * ②用一个全局的静态的常量,来保存这个唯一的实例对象
 * (3)形式三
 * ①构造器私有化
 * ②用一个私有的静态的常量,来保存这个唯一的实例对象
 * ③提供一个静态方法,来返回这个常量对象
 * 
 * 2、懒汉式
 * 延迟创建对象。当使用者来或者这个对象,要用到对象时,我再创建。
 * (1)形式一:
 * 见下面,考虑线程安全问题和性能问题
 * (2)形式二:内部类形式
 * 
 */
public class Test17 {
    @Test
    public void test1(){
        SingleEnum s1 = SingleEnum.INSTANCE;
        SingleEnum s2 = SingleEnum.INSTANCE;
        System.out.println(s1 == s2);
    }
    
    @Test
    public void test2(){
//        SingleEnum.test();//此时我并没有需要用到这个对象,但是它也创建出来了
    }
    
    @Test
    public void test3(){
        SingleClass s1 = SingleClass.INSTANCE;
        SingleClass s2 = SingleClass.INSTANCE;
        System.out.println(s1==s2);
    }
    
    @Test
    public void test4(){
        Single s1 = Single.getInstance();
        Single s2 = Single.getInstance();
        System.out.println(s1 == s2);
    }
    
    @Test
    public void test5(){
        LazyClass s1 = LazyClass.getInstance();
        LazyClass s2 = LazyClass.getInstance();
        System.out.println(s2 == s1);
    }
    
    LazyClass s1;
    LazyClass s2;
    @Test
    public void test6(){
        //匿名的内部类,继承Thread类
        Thread t1 = new Thread(){
            public void run(){
                s1 = LazyClass.getInstance();
            }
        };
        
        Thread t2 = new Thread(){
            public void run(){
                s2 = LazyClass.getInstance();
            }
        };
        
        t1.start();
        t2.start();
        
        try {
            //这里用join的目的是,为了两个子线程都执行完,再执行主线程的System.out.println(s1);
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s1 == s2);
    }
    
}
enum SingleEnum{
    INSTANCE;
//    public static void test(){
//        //..
//    }
}
class SingleClass{
    public static final SingleClass INSTANCE = new SingleClass();
    private SingleClass(){
        
    }
}
class Single{
    private static final Single INSTANCE = new Single();
    private Single(){
        
    }
    public static Single getInstance(){
        return INSTANCE;
    }
}

class LazyClass{
    private static LazyClass instance;
    private LazyClass(){
        
    }
    
    public static LazyClass getInstance(){
        if(instance == null){//提高效率
            synchronized(LazyClass.class){//当前类的Class对象
                if(instance == null){//安全判断
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new LazyClass();
                }
            }
        }
        return instance;
    }
    
    //安全没问题,但是认为不是最优的,最初的线程会有安全问题,然而也会有效率问题
/*    public synchronized static LazyClass getInstance(){
        if(instance == null){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new LazyClass();
        }
        return instance;
    }*/
    
    //有安全问题
/*    public static LazyClass getInstance(){
//        return new LazyClass();//错误的
        if(instance == null){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new LazyClass();
        }
        return instance;
    }*/
}

class Lazy{
    private Lazy(){
        
    }
    
    private static class Inner{
        public static final Lazy INSTANCE = new Lazy();//在内部类中,创建外部类的唯一对象
    }
    
    public static Lazy getInstance(){
        return Inner.INSTANCE;
    }
}

 

单例:整个系统中,某个类型的对象只有一个。

1、饿汉式

(1)枚举式

```java
public enum Single{
    INSTANCE
}
```

(2)形式二

```java
public class Single{
    public static final Single INSTANCE = new Single();
    private Single(){
        
    }
}
```

(3)形式三

```java
public class Single{
    private static final Single INSTANCE = new Single();
    private Single(){
        
    }
    public static Single getInstance(){
        return INSTANCE;
    }
}
```

2、懒汉式

(1)内部类形式

```java
public class Single{
    private Single(){}
    
    private static class Inner{
        static final Single INSTANCE = new Single();
    }
    
    public static Single getInstance(){
        return Inner.INSTANCE;
    }
    
}
```

(2)形式二

```java
public class Single{
    private static Single instance;
    private Single(){}
    
    public static Single getInstance(){
        if(instance == null){
            synchronized(Single.class){
                if(instance == null){
                    instance = new Single();
                }
            }
        }
        return instance;
    }
}
```

 

posted @ 2020-09-15 15:21  窦云鹏  阅读(133)  评论(0编辑  收藏  举报