Java多线程--单例模式的五种实现

一、恶汉模式

在这个类还没有使用到的时候就已经创建好了

public class Singleton{
    /**
     *类变量在类准备阶段就初始化了然后放在<clinit>构造方法中,
     *一旦外部调用了静态方法,那么就会初始化完成。
    */
    private static Singleton instance = new Singleton();
    private Singleton(){
    }
    public static Singleton getInstance(){
        return instance;
    }
}

二、懒汉模式-非线程安全

在需要获取Singleton对象的时候才去创建这个对象

public class Singleton{
    private static Singleton instance = null;
    private Singleton(){
    }
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

三、懒汉模式-线程安全

当两个线程同时执行到判断这个Singleton的实例instance是否为空的时候,两个线程都判断为空,那么这个时候就会返回两个实例,这样一来就不是单例模式了。因此我们想到在方法上进行加锁。

public class Singleton{
    private static Singleton instance = null;
    private Singleton(){
    }
    public synchronized static  Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

这个方式的使得一个线程等待的时候过程,降低并发性能。因此想到使用下面的方法

四、懒汉模式-双检锁

public class Singleton{
    private static Singleton instance = null;
    private Singleton(){
    }
    public static  Singleton getInstance(){
        if(instance == null){
            synchronized(Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

我们使用synchronized这个关键字将锁住一个代码块,一旦一个线程获得了这个对象锁,那么另一个线程就只能等待。当一个线程构造实例完成以后,另一个线程就进入判断条件会发现我们的实例初始化过了,不再为null。此时返回实例对象。

五、静态内部类

恶汉模式利用虚拟机加载类的特性初始化实例对象,而懒汉模式则是在类被使用的时候才会被初始化。静态内部类,当我们的类在加载的时候不会执行,只是在类被外界使用的时候才会被初始化。因此这种方式既实现了延迟加载又实现了线程安全。(这里会不会出现安全泄漏问题)


public class Singleton{
    private static Singleton instance = null;
    static{
        instance = new Singleton();
    }
    private Singleton(){
    }
    public static  Singleton getInstance(){
        return Singleton.instance;
    }
}

测试代码

package JingDongProgram;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class Test8 {
    public static void main(String[] args){

        Callable<Singleton> t1 = new Thread8();
        FutureTask<Singleton> f1 = new FutureTask<Singleton>(t1);
        Callable<Singleton> t2 = new Thread9();
        FutureTask<Singleton> f2 = new FutureTask<Singleton>(t1);
        new Thread(f1).start();
        new Thread(f2).start();

    }
}
class Thread8 implements Callable{
    @Override
    public Object call() throws Exception {
        System.out.println(Singleton.getInstance());
        return null;
    }
}
class Thread9 implements Callable{
    @Override
    public Object call() throws Exception {
        System.out.println(Singleton.getInstance());
        return null;
    }
}

输出结果

JingDongProgram.Singleton@2410eb3b
JingDongProgram.Singleton@2410eb3b

六、枚举类

public enum Singleton{
    INSTANCE;
}

七、参考文章

https://segmentfault.com/a/1190000010755849

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值