动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

30天自动登录
微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

Java单例模式

03-29 15:51 322浏览
举报 T字号
  • 大字
  • 中字
  • 小字

单例模式我们要保证类只有一个实例,并提供一个访问此实例的方法。单例模式的优点有:

  • 频繁使用的对象,可以减少创建对象所消耗的时间。
  • new操作次数的减少,对系统内存的使用频率也会减少,从而减轻GC压力,缩短GC停顿时间。

一、懒汉式

简述:懒汉式单例 在使用的时候去判断单例是否已经存在,然后再调用实例或创建实例 在懒汉式中需要考虑并发问题

1. 不使用同步方法

不使用同步方法,在不同情况下是可以实现单例的。但是在高并发的情况下可能会产生多个实例

public class SingletonLazyNoSync {
    private static SingletonLazyNoSync uniqueInstance;

    private SingletonLazyNoSync() {

    }

    // 静态工厂方法
    public static SingletonLazyNoSync getInstance() {
        // 下面是延迟实例化的方法
        if (uniqueInstance == null)
            uniqueInstance = new SingletonLazyNoSync();

        return uniqueInstance;
    }
}

2. 同步代码块

使用同步方法synchronized,能够在多线程中很好的工作,遗憾的是,效率很低

public class SingletonLazySync {
    private static SingletonLazySync uniqueInstance;

    private SingletonLazySync() {}

    public static synchronized SingletonLazySync getInstance() {
        // synchronized防止在多线程的情况下创建时会产生多个对象(但是synchronized会降低性能,同步一个方法能使程序效率下降100倍)
        // 下面是延迟实例化的方法
        if (uniqueInstance == null)
            uniqueInstance = new SingletonLazySync();

        return uniqueInstance;
    }

}

3. 双重检验加锁

使用双重检验加锁,在getInstance方法中减少同步

public class SingletonVolatile {
    // volatile保证在多线程的时候,每个线程能正确的处理这个单例
    private volatile static SingletonVolatile uniqueInstance;

    private SingletonVolatile() {}

    public static SingletonVolatile getInstance() {

        if (uniqueInstance == null)
            synchronized (SingletonVolatile.class) {
                if (uniqueInstance == null)
                    uniqueInstance = new SingletonVolatile();
            }
        return uniqueInstance;
    }
}

二、饿汉式

简述:饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了

1.静态变量

饿汉式提前实例化,但只要我们初始化类SingletonStatic,不管我们是不是调用getInstance()都会存在一个实例在内存中

public class SingletonStatic {
    private SingletonStatic() {}
    private static final SingletonStatic single = new SingletonStatic();
    public static SingletonStatic getInstance() {
        return single;
    }
}

2.静态内部类

内部类式中,实现了延迟加载,当SingletonStaticClass被加载时,其内部类不会被初始化,即SingletonStaticClass被加载到JVM的时候,不会初始化单例类。只有我们调用了getInstance(),才会加载StaticClass创建唯一的实例INSTANCE到内存中.并且也解决了懒汉式中多线程的问题.

ps:这种方法也可能创建多个实例,比如,通过反射机制来加载单例类的私有构造函数。但是,这样的情况极少

public class SingletonStaticClass {

    private static class StaticClass {
        private static final SingletonStaticClass INSTANCE = new SingletonStaticClass();
    }
    private SingletonStaticClass() {}
    public static SingletonStaticClass getInstance() {
        return StaticClass.INSTANCE;
    }
}

三、其它

public enum SingleInstance {
    INSTANCE;
    public void fun1() {
        // do something
    }
}

 

0人推荐
共同学习,写下你的评论
0条评论
我是码农
程序员我是码农

25篇文章贡献87343字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

代码小兵66904-21 20:01

6道经典算法面试题

杨晶珍05-12 16:39

简述Spring MVC的核心组件

代码小兵49806-11 16:26

SpringMVC 中的组件

代码小兵49806-11 16:28

Spring常见面试题

代码小兵92504-17 16:07

发评论

举报

0/150

取消