一個類只有一個對象實例。java
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。多線程
l 一個全局使用的類頻繁地建立與銷燬,而須要考慮節省系統資源的時候。併發
l 須要考慮資源共享的時候。高併發
需求:spa
GUI下點擊按鈕只能出現一個對話框線程
public class MainFrame extends JFrame { private JPanel contentPane; public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MainFrame frame = new MainFrame(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public MainFrame() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 625, 364); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setLayout(null); setContentPane(contentPane); //關鍵代碼 JButton button = new JButton("點擊我!"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new Dialog().setVisible(true); } }); button.setBounds(225, 109, 159, 56); contentPane.add(button); } }
public class Dialog extends JFrame { //關鍵代碼 private static Dialog instance = new Dialog(); public static Dialog getInstance() { return instance; } private JPanel contentPane; //構造方法私有化 private Dialog() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setLayout(null); setContentPane(contentPane); JLabel label = new JLabel("對話框。。。"); label.setFont(new Font("宋體", Font.PLAIN, 18)); label.setBounds(157, 117, 165, 28); contentPane.add(label); } }
JButton button = new JButton("點擊我!"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Dialog.getInstance().setVisible(true); } });
多線程下的高併發,會出現兩個線程同時搶到構造方法的資源,形成非單例現象。設計
須要解決,常見的解決方案有兩種:code
特色:只有第一次須要加載的時候才調用惟一的一次構造方法。orm
private static Dialog instance; public static Dialog getInstance() { if (instance == null) { synchronized (instance) { if (instance == null) { instance = new Dialog(); } } } return instance; } //其中,第一層if是爲了提升程序執行效率 //(若是沒有這層判斷,若是instance原本就不爲null,但還要進入synchronized代碼塊,會使程序執行效率大大下降!)
特色:該類加載到內存時就調用惟一的一次構造方法。對象
private static Object instance = new Object();