首页 > 代码库 > 张小二求职记之 单例模式(三)之决战多线程

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

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: