首页 > 其他 > 详细

单例模式

时间:2020-11-20 15:10:24      阅读:24      评论:0      收藏:0      [点我收藏+]

1.饿汉式

//饿汉式单例模式
//可能会浪费空间
public class HungryPattern {
//构造器私有
private HungryPattern() {}; private static final HungryPattern hungryPattern = new HungryPattern(); public HungryPattern getInstance() { return hungryPattern; } }

2.懒汉式

//懒汉式在单线程的情况下是OK的
public class LazyPattern {
    private LazyPattern() {
        System.out.println(Thread.currentThread().getName()+"OK!");//最后这边输出的可能不只一个线程。
    };
    
    private static LazyPattern lazyPattern;
    
    public static LazyPattern getInstance() {
        if(lazyPattern == null) {
            lazyPattern = new LazyPattern();             
        }
        return lazyPattern;
    }
//在多线程情况下会出现问题
    public static void main(String[] args) {
        for(int i = 0;i<=10;i++) {
            new Thread(()->{
                LazyPattern.getInstance();
            }).start();
        }
    }
}
结果:

Thread-0OK!
Thread-1OK!
Thread-2OK!

3.解决懒汉式的问题,双重检测锁模式

public class SynchronizedSingleton {
    private SynchronizedSingleton() {
        System.out.println(Thread.currentThread().getName()+"=> OK");
    }
    
    private static SynchronizedSingleton singleton;
    
    public static SynchronizedSingleton getInstance() {
        //双重检测锁模式
        if(singleton == null) {
            synchronized(SynchronizedSingleton.class) {//锁的是类模板
                if(singleton == null) {
                    singleton = new SynchronizedSingleton();
                }
            }
        }
        return singleton;
    }
        
    public static void main(String[] args) {
        for(int i = 0;i<=10;i++) {
            new Thread(()->{
                SynchronizedSingleton.getInstance();
            }).start();
        }
    }
}

4.因为指令的重排,双重检测加锁的方式还是有可能出现问题,这个时候就需要加一个volatile.

package Singleton;

public class SynchronizedSingleton {
    private SynchronizedSingleton() {
        System.out.println(Thread.currentThread().getName()+"=> OK");
    }
    
    private static volatile SynchronizedSingleton singleton;
    
    public static SynchronizedSingleton getInstance() {
        //双重判断加锁
        if(singleton == null) {
            synchronized(SynchronizedSingleton.class) {
                if(singleton == null) {
                    singleton = new SynchronizedSingleton();//不是一个原子性操作
                    /*1.分配内存空间
                     *2.执行构造方法,初始化对象
                     *3.把这个对象指向这个空间
                     *正常的执行顺序是123
                     *但是由于指令重排:可能编程132
                     *这个时候有可能还没有完成实例化,但是另外一个线程过来了就会返回一个null
                     *
                     *这个时候就需要对singleton对象加一个volatile 来保证指令的不重排。
                     */
                }
            }
        }
        return singleton;
    }
        
    public static void main(String[] args) {
        for(int i = 0;i<=10;i++) {
            new Thread(()->{
                SynchronizedSingleton.getInstance();
            }).start();
        }

    }
}

 

单例模式

原文:https://www.cnblogs.com/Joyce-day-day-up/p/14009948.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!