单例模式及线程安全问题

1. 什么是单例模式
        单例模式是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种模式方法。
        单例的特点:
                在任何情况下,单例类永远只有一个实例存在
                单例需要有能力为整个系统提供这一唯一实例 

2. 单例模式之懒汉式单例
        实现代码:
        public class MySingleton {
                
                private static MySingleton instance = null;
                
                private MySingleton(){}
                
                public static MySingleton getInstance() {
                        try { 
                                if(instance != null){//懒汉式 
                                        
                                }else{
                                        //创建实例之前可能会有一些准备性的耗时工作 
                                        Thread.sleep(300);
                                        instance = new MySingleton();
                                }
                        } catch (InterruptedException e) { 
                                e.printStackTrace();
                        }
                        return instance;
                }
        }
假设在创建实例前有一些准备性的耗时工作要处理,多线程调用:

        public class MyThread extends Thread{
                  
                @Override
                public void run() { 
                        System.out.println(MySingleton.getInstance().hashCode());
                }
                
                public static void main(String[] args) { 
                        
                        MyThread[] mts = new MyThread[10];
                        for(int i = 0 ; i < mts.length ; i++){
                                mts[i] = new MyThread();
                        }
                        
                        for (int j = 0; j < mts.length; j++) {
                                mts[j].start();
                        }
                }
        }
执行结果如下:

1210420568
1210420568
1935123450
1718900954
1481297610
1863264879
369539795
1210420568
1210420568
602269801

从执行结果可以看出,单例的线程安全性并没有得到保证,我们可以做出如下解决方案

三、懒汉式单例之线程安全问题
同步代码块实现
        public class MySingleton {
                
                private static MySingleton instance = null;
                
                private MySingleton(){}
                
                //public synchronized static MySingleton getInstance() {
                public static MySingleton getInstance() {
                        try { 
                                synchronized (MySingleton.class) {
                                        if(instance != null){//懒汉式 
                                                
                                        }else{
                                                //创建实例之前可能会有一些准备性的耗时工作 
                                                Thread.sleep(300);
                                                instance = new MySingleton();
                                        }
                                }
                        } catch (InterruptedException e) { 
                                e.printStackTrace();
                        }
                        return instance;
                }
        }

 

发布了157 篇原创文章 · 获赞 43 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_39581763/article/details/104197683