单例模式及线程安全问题

大兔子大兔子 提交于 2020-02-07 02:30:09

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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!