张小二求职记之 单例模式(三)之决战多线程

M:上回说的多线程的单例模式会了?

z;略懂

M:写一个吧

package 单例模式;


public class Singleton {
    private static Singleton instance=null;

    
    private Singleton()
    {
        System.out.println("单例构造函数");
    }
    
    public  static  Singleton getInstance()
    {
        if(instance==null)
        {
            instance=new Singleton();
        }
        return instance;
        
    }
    
    


    public static void main(String[] args) {
        
        //创建50个线程,对非同步的方法getinstance 就行获取对象
        for(int i=0;i<30;i++)
        {
        new Thread(new Runnable(){

            @Override
            public void run() {
               
              System.out.println(Singleton.getInstance());
            }
            
            
        }).start();
        }
        
        
    
    }

}
部分结果如下,发现出现了不同的实例
例构造函数
单例构造函数
单例模式.Singleton@75da931b
单例构造函数
单例构造函数
单例模式.Singleton@34780af5
单例模式.Singleton@34780af5
单例构造函数
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@34780af5
单例模式.Singleton@2b1be57f
单例模式.Singleton@157ee3e5
单例模式.Singleton@2b1be57f
单例模式.Singleton@60f00e0f
单例模式.Singleton@157ee3e5

加入synchronized部分结果如下:全部都唯一啊,你自己试试。

例构造函数
单例模式.Singleton@78214f6b
单例模式.Singleton@78214f6b
单例模式.Singleton@78214f6b
单例模式.Singleton@78214f6b
单例模式.Singleton@78214f6b
单例模式.Singleton@78214f6b

M:用了synchronized方法是吧,修饰静态方法,相当于对什么加锁

,相当于对sinleton.class加锁

M:不错,多线程可以提高程序的并发程度,从而提高程序执行效率,但是多线程本身,尤其是同步,会引起锁的竞争,我就问你了,如何减少锁的竞争,改造本方法,并举个其他的例子?

z:减少的所得粒度和上锁的范围。比如数据库中有对表 页 行 加锁,粒度低了,锁的竞争就减少了。

比如在读写锁,如果只有一种锁的,那么SS也是互斥的,通过将锁分割成读写锁,减少了竞争。

 

对于队列解锁,我可以设置头设置一个锁,尾巴设置一个锁,这样不就减小了锁的粒度,

还有并行的hashmap、

M:呵呵,知道不少,写代码吧,分析这个问题:

z: 本文中synchronzide同步的粒度大,因为instance=!=null不用加锁。

所以改造如下;

 

package 单例模式;


public class Singleton {
    private static Singleton instance=null;

    
    private Singleton()
    {
        System.out.println("单例构造函数");
    }
    
    public  static  Singleton getInstance()
    {
        if(instance==null)
        {
        synchronized(Singleton.class)
        {
        if(instance==null)
        {
            instance=new Singleton();
        }
        }
        }
        return instance;
        
    }
    
    


    public static void main(String[] args) {
        
        //创建50个线程,对非同步的方法getinstance 就行获取对象
        for(int i=0;i<30;i++)
        {
        new Thread(new Runnable(){

            @Override
            public void run() {
               
              System.out.println(Singleton.getInstance());
            }
            
            
        }).start();
        }
        
        
        
        
               

    
    }

}

 

M:双重锁检查,为什么要双重锁?

第一步:只有为空才会进同步块,说了,如果有了实例就直接返回结果

第二部:判断为空:按照线程的不可确定性,两个线程同时判断

if(instance==null) 都会先后进入同步快,为出现创建两个实例

package 单例模式;


public class Singleton {
    private static Singleton instance=null;

    
    private Singleton()
    {
        System.out.println("单例构造函数");
    }
    
    public  static  Singleton getInstance()
    {
        if(instance==null)
        {
        synchronized(Singleton.class)
        {
    
        
            instance=new Singleton();
        
        }
        }
        return instance;
        
    }
    
    


    public static void main(String[] args) {
        
        //创建50个线程,对非同步的方法getinstance 就行获取对象
        for(int i=0;i<100;i++)
        {
        new Thread(new Runnable(){

            @Override
            public void run() {
               
              System.out.println(Singleton.getInstance());
            }
            
            
        }).start();
        }
        
        
        
        
        
    
        

    
    }

}
结果出现重复

例构造函数
单例构造函数
单例模式.Singleton@46993aaa
单例模式.Singleton@52e5376a
单例模式.Singleton@46993aaa
单例模式.Singleton@46993aaa
单例模式.Singleton@46993aaa
单例模式.Singleton@46993aaa
单例构造函数
单例模式.Singleton@157ee3e5
单例模式.Singleton@46993aaa
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单例模式.Singleton@157ee3e5
单M:

单例模式咱们告一段落,下面将会NIO,在NIO有个所谓的观察者模式,说白了,就是事件驱动的。NIO叫做 new io ,也可叫no-blocking 就是非阻塞,还有的叫 Net io,就是网络加 io,他对以往的socket编程进行改进,同时IO函数进行改进,我们重点关注一下IO和网络编程,顺带着把观察者模式解决了,回去吧

 

 

z:

张小二求职记之 单例模式(三)之决战多线程,布布扣,bubuko.com

张小二求职记之 单例模式(三)之决战多线程

上一篇:Python3.x和Python2.x的区别


下一篇:【模板专区】 C++排序模板