单例模式(5种实现方式)

简介: 单例模式(5种实现方式)

1.饿汉式(不支持并发)

此模式只能运行在单线程下,且类在加载时就已经创建好了实例,不管需不需要用。

package com.lys;

//饿汉式
public class Singleton1 {
    private Singleton1() {
    }
    private static Singleton1 instance = new Singleton1();
    
    public static Singleton1 getInstance(){
        return instance;
    }

}

2.懒汉式(不支持并发)

此模式只能运行在单线程下,在调用获取实例的方法时才创建实例。

package com.lys;

//懒汉式、不支持多并发
public class Singleton2 {
    private Singleton2() {
    }
    private static Singleton2 instance = null;
    public static Singleton2 getInstance(){
        if (instance == null){
            instance = new Singleton2();
        }
        return instance;
    }

}

3.懒汉式(支持并发、synchronized)

synchronized 锁住了整个方法,当有多个线程需要访问方法时,不管实例有没有创建,都会要排队等待才能拿到实例,效率低。
需要改进:只有第一次创建实例时才需要锁,其他时候不需要加锁。

package com.lys;

//懒汉式、支持多并发、效率低
public class Singleton3 {
    private Singleton3() {
    }
    private static Singleton3 instance = null;
    public synchronized static Singleton3 getInstance(){
        if (instance == null){
            instance = new Singleton3();
        }
        return instance;
    }

}

4.双重检查锁 (volatile)--常用

volatile 关键字保证了内存可见性,所有线程都会去主存中取数据而不是在线程的缓存中取,保证了数据的更新能实时地对任何线程可见。
假如有两个线程同时到达了1,它们都去创建实例,这时候如果没有第二次判断,就会多次创建实例了。二次判断保证了多线程下只创建一个实例。

package com.lys;

//double checked locking、支持多并发、效率高、添加volatile关键字
public class Singleton4 {
    private Singleton4() {
    }
    private volatile static Singleton4 instance = null;
    public static Singleton4 getInstance(){
        if (instance == null){//1
            synchronized (Singleton4.class) {
                if (instance == null)//2
                    instance = new Singleton4();
            }
        }
        return instance;
    }
}

5.静态私有内部类(最常用)

内部类的好处:内部类在被调用的时候才实例化其静态成员变量,高!

package com.lys;

//静态私有内部类、支持多并发、效率高、
public class Singleton5 {
    private Singleton5() {
    }
    private static class SingletonHolder{
        private static Singleton5 instance = new Singleton5();
    }
    public static Singleton5 getInstance(){
        return SingletonHolder.instance;
    }
}
相关文章
|
4月前
|
设计模式 缓存 安全
【设计模式】单例模式:确保类只有一个实例
【设计模式】单例模式:确保类只有一个实例
43 0
|
4月前
|
C++
C++实现单例模式-多种方式比较
单例模式,面试中经常被问到,但是很多人只会最简单的单例模型,可能连多线程都没考虑到,本文章从最简单的单例,到认为是最佳的单例模式实现方式,单例模式没有什么知识点,直接上源码
70 0
|
10月前
|
设计模式 存储 安全
八种创建单例模式的方式-懒汉式与饿汉式及枚举
八种创建单例模式的方式-懒汉式与饿汉式及枚举
106 2
|
11月前
|
设计模式 安全 Java
JAVA设计模式1:单例模式,确保每个类只能有一个实例
JAVA设计模式1:单例模式,确保每个类只能有一个实例
|
11月前
|
设计模式 安全 Java
特殊类设计及单例模式(C++)
特殊类设计及单例模式(C++)
72 1
|
3月前
|
设计模式 SQL 安全
Java设计模式:单例模式之六种实现方式详解(二)
Java设计模式:单例模式之六种实现方式详解(二)
|
12月前
单例模式设计(一)
饿汉模式 由名字我们就可以知道 "饿汉" 嘛,就比较急切,在类加载的时候就创建实例: 1. 写一个类,在本类中构造实例,用static修饰,直接创建出来(提供一个现有的实例) 2. 在本类中写一个方法获取到上面的实例 3. 将这个类的构造方法设置为私有的,让外部不能 new 这个对象
58 0
|
安全 Java 编译器
单例模式的4种实现方式
单例模式的4种实现方式
93 0
|
4月前
|
设计模式 安全 Java
Java设计模式—单例模式的实现方式和使用场景
那么为什么要有单例模式呢?这是因为有的对象的创建和销毁开销比较大,比如数据库的连接对象。所以我们就可以使用单例模式来对这些对象进行复用,从而避免频繁创建对象而造成大量的资源开销。
125 1
|
12月前
|
安全
单例模式设计(二)
根据上面的 "懒汉模式" 和 "饿汉模式"。我们可以知道,懒汉模式,它只是负责读取,没有修改。而 " 饿汉模式 " 是既读取,也进行修改。所以来说, "懒汉模式" 是线程安全的, "饿汉模式" 是线程不安全的。
58 0