单例模式的几种实现方式解析

熊孩纸 阅读:396 2020-09-30 21:41:13 评论:0
方式一、
/** 
 * 饿汉式 
 * 类加载到内存后,就实例化一个单例,JVM保证线程安全 
 * 简单实用,推荐使用! 
 * 唯一缺点:类装载时就完成实例化 
 */ 
public class Singleton01{
    
    private static final Singleton01 INSTANCE = new Singleton01 (); 
 
    private Singleton01() {
   }; 
 
    public static Singleton01 getInstance() {
    
        return INSTANCE; 
    } 
 
	/** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        Singleton01 s1= Singleton01.getInstance(); 
        Singleton01 s2= Singleton01.getInstance(); 
        System.out.println(s1== s2); 
    } 
} 

方式二

/** 
 * 同方式一 
 */ 
 
public class Singleton02 {
    
    private static final Singleton02 INSTANCE; 
    static {
    
        INSTANCE = new Singleton02(); 
    } 
 
    private Singleton02 () {
   }; 
 
    public static Singleton02  getInstance() {
    
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        Singleton02 s1 = Singleton02 .getInstance(); 
        Singleton02 s2 = Singleton02 .getInstance(); 
        System.out.println(s1 == s2); 
    } 
} 

方式三

/** 
 * lazy loading 
 * 也称懒汉式 
 * 多线程下并不能保证单例 
 */ 
public class Singleton03{
    
    private static Singleton03 INSTANCE; 
 
    private Singleton03 () {
    
    } 
 
    public static Singleton03 getInstance() {
    
        if (INSTANCE == null) {
    
            try {
    
                Thread.sleep(1); 
            } catch (InterruptedException e) {
    
                e.printStackTrace(); 
            } 
            INSTANCE = new Singleton03(); 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()-> 
                System.out.println(Singleton03.getInstance().hashCode()) 
            ).start(); 
        } 
    } 
} 

方式四

/** 
 * lazy loading 
 * 也称懒汉式 
 * 通过synchronized 实现多线程下保证单例 
 *  
 */ 
public class Singleton04{
    
    private static Singleton04 INSTANCE; 
 
    private Singleton04() {
    
    } 
 
    public static synchronized Singleton04 getInstance() {
    
        if (INSTANCE == null) {
    
            try {
    
                Thread.sleep(1); 
            } catch (InterruptedException e) {
    
                e.printStackTrace(); 
            } 
            INSTANCE = new Singleton04(); 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton04.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式五

/** 
 * lazy loading 
 * 也称懒汉式 
 * 减少synchronized代码块以提高效率,但多线程下不能保证单例 
 *  
 */ 
public class Singleton05 {
    
    private static Singleton05 INSTANCE; 
 
    private Singleton05 () {
    
    } 
 
    public static Singleton05 getInstance() {
    
        if (INSTANCE == null) {
    
            synchronized (Singleton05.class) {
    
                try {
    
                    Thread.sleep(1); 
                } catch (InterruptedException e) {
    
                    e.printStackTrace(); 
                } 
                INSTANCE = new Singleton05 (); 
            } 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton05.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式六

/** 
 * lazy loading 
 * 也称懒汉式 
 * 双重检查保证多线程下单例 
 * 推荐使用 
 */ 
public class Singleton06 {
    
    private static volatile Singleton06 INSTANCE;  
 
    private Singleton06 () {
    
    } 
 
    public static Singleton06 getInstance() {
    
        if (INSTANCE == null) {
    
            //双重检查 
            synchronized (Singleton06.class) {
    
                if(INSTANCE == null) {
    
                    try {
    
                        Thread.sleep(1); 
                    } catch (InterruptedException e) {
    
                        e.printStackTrace(); 
                    } 
                    INSTANCE = new Singleton06(); 
                } 
            } 
        } 
        return INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton06.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式七

/** 
 * 静态内部类方式 
 * JVM保证单例 
 * 加载外部类时不会加载内部类,这样可以实现懒加载 
 * 推荐使用 
 */ 
public class Singleton07 {
    
 
    private Singleton07 () {
    
    } 
 
    private static class Singleton07Holder {
    
        private final static Singleton07 INSTANCE = new Singleton07(); 
    } 
 
    public static Singleton07 getInstance() {
    
        return Singleton07Holder.INSTANCE; 
    } 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton07.getInstance().hashCode()); 
            }).start(); 
        } 
    } 
} 

方式八

/** 
 * 枚举单例,JAVA 大神推荐 
 * 不仅可以解决线程同步,还可以防止反序列化,语义上不太符合业务,酌情使用 
 */ 
public enum Singleton08 {
    
 
    INSTANCE; 
 
    /** 
	 * 业务代码 
	 */ 
    public void business() {
    
        System.out.println("TODO"); 
    } 
 
    public static void main(String[] args) {
    
        for(int i=0; i<100; i++) {
    
            new Thread(()->{
    
                System.out.println(Singleton08.INSTANCE.hashCode()); 
            }).start(); 
        } 
    } 
} 
标签:java
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
KIKK导航

KIKK导航

关注我们