java單例設計模式
阿新 • • 發佈:2018-05-30
返回 線程 clas pub 問題: private 利用 線程安全 run
什麽是單例設計模式
單例即只有一個實例,該模式的作用是保證程序中某個類的對象只有一個。
單例模式分為懶漢式和餓漢式。
懶漢式
class Student{ static Student st; private Student(){} public static Student getInstance(){ //引用數據類型屬性在內存中的默認值為null //如果值為null 只創建一次對象 if(st==null){ st = new Student(); } return st; } } public class Test1 { public static void main(String[] args) { // 利用hascode 相等 是單例 Student tes1 = Student.getInstance(); System.out.println(tes1.hashCode()); Student tes2 = Student.getInstance(); System.out.println(tes2.hashCode()); } }
以上可以看出結果的hasCode值是相同的只創建了一個對象
但是這種模式在多線程的情況下會產生線程安全問題:
class Teacher{ static Teacher s; private Teacher(){} public static Teacher getInstance(){ if(s == null){ s = new Teacher(); } return s; } } class StudentThread extends Thread{ public void run(){ for(int i = 0;i<3;i++){ Teacher ss = Teacher.getInstance(); System.out.println(ss.hashCode()); } } } public class Test2 { public static void main(String[] args) { //單例模式在多線程中存在線程安全問題 需要解決線程安全 //創建線程 StudentThread tt1 = new StudentThread(); StudentThread tt2 = new StudentThread(); //就緒狀態 tt1.start(); tt2.start(); } }
如果在運行多次的情況下會出現hasCode不一定都一樣 這就出現了線程安全問題:
解決辦法只需要將返回對象的方法設置為同步方法即可
public synchronized static Teacher getInstance(){ if(s == null){ s = new Teacher(); } return s; }
餓漢式
//餓漢式 class Hangle{ //創建靜態屬性的時候就賦值 並且只執行一次 也就是說只創建一次對象 static Hangle ha = new Hangle(); public static Hangle getInstance(){ return ha; } } class SingleThread extends Thread{ public void run(){ for(int i = 0;i<4;i++){ Hangle hh = Hangle.ha; System.out.println(hh.hashCode()); } } } public class Test3 { public static void main(String[] args) { SingleThread tt1 = new SingleThread(); SingleThread tt2 = new SingleThread(); //就緒狀態 tt1.start(); tt2.start(); // 總結: 懶漢式 在多線程環境中會發生線程安全問題 (可以解決線程問題) //而餓漢式不管是在單線程還是在多線程中 不存在線程安全問題 建議定義單例模式的話 用餓漢式 //餓漢式單例模式要比懶漢式效率高 } }
java單例設計模式