JAVA就業面試題之單例模式

JAVA就業面試題
4.1單例模式java

​ 單例,就是整個程序有且僅有一個實例。該類負責建立本身的對象,同時確保只有一個對象被建立。

特色面試

持有本身類型的屬性
類構造器私有
對外提供獲取實例的靜態方法

4.1.1 懶漢式安全

/**多線程

  • Created by 張晨光 on 2020/6/12 11:07
  • 懶漢式
    */
    public class Banzhang {
    //1.本身類的靜態屬性
    private static Banzhang bz;
    //2.私有的構造方法
    private Banzhang(){}
    //3.提供對外獲取實例的靜態方法
    public static Banzhang getInstance(){
    if(bz==null)
    bz= new Banzhang();
    return bz;
    }
    }

問題,線程不安全,延遲初始化,問題在 12行;
4.1.2 餓漢式ide

線程安全,比較經常使用,但容易產生垃圾,由於一開始就初始化測試

/**線程

  • Created by 張晨光 on 2020/6/12 11:12
  • 餓漢式
    */
    public class SingleTon {
    //1.靜態本身自己屬性;
    private static SingleTon singleTon=new SingleTon();
    //2.私有構造方法;
    private SingleTon(){}
    //3.提供靜態的方法實例;
    public static SingleTon getInstance(){
    return singleTon;
    }
    }

餓漢式:當即加載;code

懶漢式:延遲加載;–》節省資源
4.1.3 雙重鎖模式對象

雙重檢查模式,進行了兩次的判斷,第一次是爲了不不要的實例,第二次是爲了進行同步,避免多線程問題。因爲singleton=new Singleton()對象的建立在JVM中可能會進行重排序,在多線程訪問下存在風險,使用volatile修飾signleton實例變量有效,解決該問題。排序

/**

  • Created by 張晨光 on 2020/6/12 11:22
  • 雙重鎖模式
    */
    public class Monitor {
    private volatile static Monitor monitor;
    private Monitor(){}
    private static Monitor getInstance(){
    if(monitor==null){
    synchronized (Monitor.class){
    if(monitor==null)
    monitor=new Monitor();
    }
    }
    return monitor;
    }
    }

4.1.4 靜態內部類

​ 只有第一次調用getInstance方法時,虛擬機才加載 Inner 並初始化instance ,只有一個線程能夠得到對象的初始化鎖,其餘線程沒法進行初始化,保證對象的惟一性。目前此方式是全部單例模式中最推薦的模式,但具體仍是根據項目選擇。

/**

  • Created by 張晨光 on 2020/6/12 11:29
  • 靜態內部類
    */
    public class JtSingleTon {
    //private static JtSingleTon jtSingleTon;
    private JtSingleTon(){}
    private static JtSingleTon getInstance(){
    return Inner.jtSingleTon;
    }
    private static class Inner{
    private static final JtSingleTon jtSingleTon=new JtSingleTon();
    }
    }

4.1.5 枚舉實現

首先是再瞭解一下枚舉

/**

  • Created by 張晨光 on 2020/6/12 15:36
  • 枚舉測試;先來理解枚舉的原理;
    */
    public enum EnumSingleTon {
    INSTANCE; //關鍵字;
    private EnumSingleTon(){
    System.out.println("初始化...");
    }
    public static EnumSingleTon getInstance(){
    return INSTANCE;
    }
    }

使用枚舉的這種,只初始化一次的特徵,來實現單例。

package single;

/**

  • Created by 張晨光 on 2020/6/12 15:42
  • User類,使用枚舉實現;
    */
    public class User {
    //1.私有的構造方法;
    private User(){}
    //2.利用枚舉類來獲取實例;在這裏放一個枚舉SingleTon
    static enum SingleTon{
    //有一個枚舉對象,天生爲單例;
    INSTANCE;
    private User user;
    //私有的枚舉構造方法;只被初始化一次;
    private SingleTon(){
    user=new User();
    }
    //由枚舉提供一個獲取User類的實例方法
    public User getInstance(){
    return user;
    }
    }
    //3.經過枚舉來獲取單例;
    public static User getInstance(){
    return SingleTon.INSTANCE.getInstance();
    }
    }

//調用測試方法,來測試User類是否單例的實現;br/>@Test
public void testEnumUser(){
User est1=User.getInstance();
User est2=User.getInstance();
System.out.println(est1);
System.out.println(est2);
}

總結:

​ 1.理解:單例的概念

​ 2.瞭解:懶漢式和餓漢式;建議會寫靜態內部類的實現;

用枚舉類來獲取實例;在這裏放一個枚舉SingleTon
static enum SingleTon{
//有一個枚舉對象,天生爲單例;
INSTANCE;
private User user;
//私有的枚舉構造方法;只被初始化一次;
private SingleTon(){
user=new User();
}
//由枚舉提供一個獲取User類的實例方法
public User getInstance(){
return user;
}
}
//3.經過枚舉來獲取單例;
public static User getInstance(){
return SingleTon.INSTANCE.getInstance();
}
}

//調用測試方法,來測試User類是否單例的實現;
@Test
public void testEnumUser(){
    User est1=User.getInstance();
    User est2=User.getInstance();
    System.out.println(est1);
    System.out.println(est2);
}

    9
    10

總結:

​ 1.理解:單例的概念

​ 2.瞭解:懶漢式和餓漢式;建議會寫靜態內部類的實現;

​ 3.其餘的知道便可,根據本身的程度,看看就好了。
————————————————
相關文章
相關標籤/搜索