码迷,mamicode.com
首页 > 移动开发 > 详细

Android-Java-单例模式优化&多线程并发

时间:2019-01-07 23:33:42      阅读:296      评论:0      收藏:0      [点我收藏+]

标签:art   ring   分享   col   rgs   操作   共享   ret   private   

上一篇博客,Android-Java单例模式,介绍了在真实开发过程中,普遍使用的几种单例模式,而今天这篇博客,将要对单利模式进行优化 并且 通过多线程并发来分析

 

单利模式的优化:

对于为什么会出现安全问题,可以看Android-多线程安全问题-synchronized博客

package android.java.thread14;

/**
 * 单例模式优化
 */
public class SingletonPattern {

    private SingletonPattern() {
    }

    /**
     * 俄汉式:多线程并发是安全??的,因为此类一加载就实例化了
     */
    private static final SingletonPattern SINGLETON_PATTERN = new SingletonPattern();

    public static SingletonPattern getInstance1() {
        return SINGLETON_PATTERN; // 如果这里对SINGLETON_PATTERN共享数据进行操作,多线程并发不安全!
    }



    /**
     * 懒汉式:需要进行 静态方法 synchronized(锁?? SingletonPattern.class)
     * 此方式性能低:因为线程每次调用此方法都需要判断锁
     * 需要明白CPU执行执行多线程的随机性,并用以下代码方式解决 多线程并发
     */
    private static SingletonPattern singletonPattern = null;

    public static synchronized SingletonPattern getInstance2() {
        if (null == singletonPattern) { // 这里对singletonPattern共享数据进行操作,多线程并发不安全!
            singletonPattern = new SingletonPattern(); // 这里对singletonPattern共享数据进行操作,多线程并发不安全!
            System.out.println(Thread.currentThread().getName() + ">>>>>>> 懒汉式1 单例模式实例化了");
        }
        return singletonPattern;
    }



    /**
     * 懒汉式:对性能要求高 可以  synchronized + if双重判断
     * 需要明白CPU执行执行多线程的随机性,并用以下代码方式解决 多线程并发
     */
    private static SingletonPattern singleton = null;

    private static final Object objectLock = new Object(); // 定义一把同步锁??

    public static SingletonPattern getInstance3() {
        if (null == singleton) {

            synchronized (objectLock) {

                if (null == singleton) {
                    singleton = new SingletonPattern();
                    System.out.println(Thread.currentThread().getName() + ">>>>>>> 懒汉式2 单例模式实例化了");
                }

            }

        }
        return singleton;
    }
}

 

多线程并发实例化单例模式:

package android.java.thread14;

/**
 * 执行任务,此任务可以给线程运行
 */
class DoRunnable implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            // doRunnable1();
            // doRunnable2();
            doRunnable3();

            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void doRunnable1() {
        SingletonPattern.getInstance1();
    }

    private void doRunnable2() {
        SingletonPattern.getInstance2();
    }

    private void doRunnable3() {
        SingletonPattern.getInstance3();
    }
}

public class Test {

    public static void main(String[] args) {
        // 实例化任务
        DoRunnable doRunnable = new DoRunnable();

        // 开启三个线程
        new Thread(doRunnable).start();
        new Thread(doRunnable).start();
        new Thread(doRunnable).start();
    }

}

 

执行结果,CPU随机性:

技术分享图片

 

俄汉式:性能提高的同时 又保证了多线程的并发-安全

/**
     * 懒汉式:对性能要求高 可以  synchronized + if双重判断
     * 需要明白CPU执行执行多线程的随机性,并用以下代码方式解决 多线程并发
     */
    private static SingletonPattern singleton = null;

    private static final Object objectLock = new Object(); // 定义一把同步锁??

    public static SingletonPattern getInstance3() {
        
        // 假设CPU随机第四步:Thread-1 现在判断不为null,进不去
        if (null == singleton) {
            // 假设CPU随机第一步:Thread-0 执行到这里CPU去执行其他Thread-2线程了     假设CPU随机第二步:Thread-2线程在这里判断锁,然后进去了       
            synchronized (objectLock) {
                
                if (null == singleton) {
                    singleton = new SingletonPattern();
                    System.out.println(Thread.currentThread().getName() + ">>>>>>> 懒汉式2 单例模式实例化了");
                }
            
            } // 假设CPU随机第三步:Thread-2 执行完毕

        }
        return singleton;
    }

 

Android-Java-单例模式优化&多线程并发

标签:art   ring   分享   col   rgs   操作   共享   ret   private   

原文地址:https://www.cnblogs.com/android-deli/p/10236266.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!