Java多线程7 单例懒汉式的并发访问

package Thread;
/*
单例设计模式:懒汉式并发运行时的安全问题
 */
//饿汉式设计模式
class Single1{
    private Single1(){}
    private final static Single1 S1 = new Single1();
    public static Single1 getSing(){
        return S1;
    }
}
//懒汉式设计模式
class Single2{
    private Single2(){}
    private static Single2 S2 = null;
    public synchronized static Single2 getSingle(){
        if(S2==null){
            S2 = new Single2();
        }
        return S2;
    }
}
class ThreadDemo implements Runnable{
    public void run(){
        //Single1 S =Single1.getSing();
        /*
        饿汉式并发运行时不会出现安全问题:1.有共享数据 实例 S1 2.但是对共享数据的操作代码已有一行,不会出现CPU切换导致的数据错误
         */
        Single2 S =Single2.getSingle();
        /*
        懒汉式并发运行会发生并发运行时的安全问题:1.有共享数据  S2。 2对共享数据的操作代码不只一行
        安全问题是:实例不再是唯一的————单例设计模式废掉
         */
    }
}
public class ThreadSingle {
    public static void main(String[] args){
        ThreadDemo t = new ThreadDemo();
        Thread T1= new Thread(t);
        Thread T2 = new Thread(t);
        T1.start();
        T2.start();
    }
}

单例设计模式就不再多说,

/*
饿汉式并发运行时不会出现安全问题:1.有共享数据 实例 S1 2.但是对共享数据的操作代码已有一行,不会出现CPU切换导致的数据错误
 */
/*
懒汉式并发运行会发生并发运行时的安全问题:1.有共享数据  S2。 2对共享数据的操作代码不只一行
安全问题是:实例不再是唯一的————单例设计模式废掉
 */

But

加入同步解决了,并发运行产生的安全问题,但是,同步的出现降低了效率(无路是哪一个路径都要去判断是否为相应的锁)

解决代码:

package Thread;
/*
单例设计模式:懒汉式并发运行时的安全问题
 */
//饿汉式设计模式
class Single1{
    private Single1(){}
    private final static Single1 S1 = new Single1();
    public static Single1 getSing(){
        return S1;
    }
}
//懒汉式设计模式
class Single2{
    private Single2(){}
    private static Single2 S2 = null;
    public  static Single2 getSingle(){
        if(S2==null) {
            synchronized (Single2.class) {
                if (S2 == null) {
                    S2 = new Single2();
                }
            }
        }
            return S2;
    }
}
class ThreadDemo implements Runnable{
    public void run(){
        while(true) {
            //Single1 S =Single1.getSing();
        /*
        饿汉式并发运行时不会出现安全问题:1.有共享数据 实例 S1 2.但是对共享数据的操作代码已有一行,不会出现CPU切换导致的数据错误
         */
            Single2 S = Single2.getSingle();
        /*
        懒汉式并发运行会发生并发运行时的安全问题:1.有共享数据  S2。 2对共享数据的操作代码不只一行
        安全问题是:实例不再是唯一的————单例设计模式废掉
         */
        }
    }
}
public class ThreadSingle {
    public static void main(String[] args){
        ThreadDemo t = new ThreadDemo();
        Thread T1= new Thread(t);
        Thread T2 = new Thread(t);
        T1.start();
        T2.start();
    }
}
/懒汉式设计模式
class Single2{
    private Single2(){}
    private static Single2 S2 = null;
    public  static Single2 getSingle(){
        if(S2==null) {/——————————————————————————————————————/1
            synchronized (Single2.class) {/——————————————————/2
                if (S2 == null) {/———————————————————————————/3
                    S2 = new Single2();/——————————————————————/4
                }
            }
        }
            return S2;
    }
}

通过双重判断的方式,解决效率问题,减少锁的判断次数

分析:首先将线程任务设置为无穷(也可以设置一个比较大的循环次数——这样比较好理解)

线程0判断1 获取2 的锁,判断3  ,此时CPU切换,线程1判断1 ,判断2 已经被锁起来。CPU切回0 实例赋值。以后无论是哪一个线程都会在判断1 时停止。虽然看着是多了几行代码,但是就大量循环来说,是提高了效率

猜你喜欢

转载自blog.csdn.net/Stitch__/article/details/81632136