抱歉,你查看的文章不存在

设计模式笔记(八)——单例模式 原

1. 是什么——定义

一个类只有一个对象实例。

2. 为什么——特点

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

3. 什么时候用——适用性

l  一个全局使用的类频繁地创建与销毁,而需要考虑节省系统资源的时候。

l  需要考虑资源共享的时候。

4. 怎么用——实际应用

需求:

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);
    }
});

5. 多线程下的单例模式

多线程下的高并发,会出现两个线程同时抢到构造方法的资源,造成非单例现象。

需要解决,常见的解决方案有两种:

5.1  懒汉单例模式

特点:只有第一次需要加载的时候才调用唯一的一次构造方法。

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代码块,会使程序执行效率大大降低!)

5.2  饿汉单例模式

特点:该类加载到内存时就调用唯一的一次构造方法。

private static Object instance = new Object();

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

LinkedBear的个人空间

0 篇文章14 人订阅

相关文章

扫码关注云+社区

领取腾讯云代金券