單例模式:餓漢式和懶漢式
阿新 • • 發佈:2018-12-17
餓漢式:載入類的時候,就建立了物件
/**
* 餓漢式:載入類的時候,就建立了物件
*/
public class Ehanshi {
// 建立物件
private static Ehanshi ehanshi = new Ehanshi();
// 無參構造
private Ehanshi() {
}
public Ehanshi getInstance() {
return ehanshi;
}
}
懶漢式:需要用的時候,才會建立物件
public class LhanShi { /** * 懶漢式的多裡會遇到執行緒安全問題 * * 有可能會獲取到多個例項 */ private static LhanShi lhanShi; private LhanShi() { } public static LhanShi getInstance() { if (lhanShi == null) { try { // 執行緒休眠 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }; lhanShi = new LhanShi(); } return lhanShi; } public static void main(String[] args) { // 開闢10條執行緒 for (int i= 0;i<10;i++){ new Thread(new Runnable() { @Override public void run() { LhanShi instance = LhanShi.getInstance(); System.out.println(instance.hashCode()); } }).start(); } } }
既然懶漢式會出問題,如何解決懶漢式的執行緒同步問題?
解決方案:加上同步synchronized
/** * 需要用的時候,才會建立物件 */ public class LhanShi { /** * 懶漢式的多裡會遇到執行緒安全問題 * * 有可能會獲取到多個例項 */ private static LhanShi lhanShi; private LhanShi() { } /** * synchronized:方法使用synchronized修飾,此方法同一時間只允許一條執行緒訪問 * @return */ public synchronized static LhanShi getInstance() { if (lhanShi == null) { try { // 執行緒休眠 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }; lhanShi = new LhanShi(); } return lhanShi; } public static void main(String[] args) { // 開闢10條執行緒 for (int i= 0;i<10;i++){ new Thread(new Runnable() { @Override public void run() { LhanShi instance = LhanShi.getInstance(); System.out.println(instance.hashCode()); } }).start(); } } }