zoukankan      html  css  js  c++  java
  • 单例模式的线程安全问题

    例会带来什么问题?

    如果多个线程同时调用这个实例,会有线程安全的问题

     

    单例一般用在什么地方?

    单例的目的是为了保证运行时只有唯一的一个实例,最常用的地方比如拿到数据库的连接,或者Spring的中创建BeanFactory操作,而这些操作都是调用他们的方法来执行某个特定的动作。

     

    首先先来认识下两种模式:  恶汉式  懒汉式

     

    public class MyFactory {
        
    //    //饿汉式  立即创建
    //    private static MyFactory instance = new MyFactory();
    //    public static MyFactory getInstance(){
    //        return instance;
    //    }
    
        //懒汉式用到的时候在创建,不用就不创建(有线程安全问题)
        private static MyFactory instance = null;
        public static MyFactory getInstance(){
         instance = new MyFactory();return instance;
        }   
    }

     

    下面总结一下解决线程安全的几种方式:

    方法一:在MyFactory 中加入了一个私有静态内部类instanceHolder ,对外提供的接口是 getInstance()方法,也就是只有在MyFactory.getInstance()的时候,instance对象才会被创建,,没有使用同步。保证了只有一个实例,还同时具有了Lazy的特性

    public class MyFactory {
            private static class instanceHolder {   
                public static MyFactory instance = new MyFactory();   
            }   
          
            public static MyFactory getInstance() {   
                return MyFactory.instanceHolder.instance;   
            }   
    }

    测试代码

    import static org.junit.Assert.*;
    import org.junit.Test;
    public class MyFactoryTest {
        @Test
        public void testGetResource() {
            MyFactory mf1 = MyFactory.getInstance();
            MyFactory mf2 = MyFactory.getInstance();
            System.out.println(mf1 != null);//true
            System.out.println(mf1 == mf2);//true
        }
    }

    方式二:(懒汉式)

    这种方式也没有使用同步,并且确保了调用static getInstance()方法时才创建MyFactory的引用,

      private static MyFactory instance = new MyFactory();
    public static MyFactory getInstance() {   return instance; }

    测试代码:同方法一

    方式三:使用synchronized 通常会锁定整个方法的是比较耗费资源的,实际会产生多线程访问问题的是这一句代码instance = new MyFactory();

    为了减少资源的消耗,只锁这一句就行了, 两个线程并发地进入第一次判断instance是否为空的if 语句内部,一个线程获得了锁执行new操作,另一个线程被阻塞,

    当第一个线程执行完毕之后,第二个线程如果直接进行new操作也是不安全的。为了避免第二次new操作,添加第二次条件判断,既二次检查

        private static MyFactory instance;
        public static MyFactory getInstance(){
            if(instance == null){
                synchronized (MyFactory.class) {
                    if(instance == null){
                        instance = new MyFactory();
                    }
                }
            }
            return instance;
        }    

    测试代码 同方法一

     

  • 相关阅读:
    HDU 3068 最长回文
    UVa 1377 / LA 3667 Ruler
    HDU 1540 Tunnel Warfare
    POJ 3450 Corporate Identity
    外贸网站成功运营五个要点
    SEO白帽必备孙子兵法之三十六计
    修改zencart模版的相关资料
    怎么做友情链接,PR值即将更新之际 教你10招快速提升PR值到4
    基于zencart搭建外贸网站流程
    网站内链优化需要考虑的方面
  • 原文地址:https://www.cnblogs.com/lnzr/p/4187404.html
Copyright © 2011-2022 走看看