zoukankan      html  css  js  c++  java
  • java常用设计模式一:单例模式

     1、饿汉式

    package singleton.demo;
    
    /**
     * @author Administrator
     * @date 2019/01/07
     */
    public class Singleton {
        //在调用getInstance方法前,实例已经创建好
        private static Singleton instance = new Singleton();
    
        //私有构造,防止被实例化
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    2、懒汉式

    package singleton.demo;
    
    /**
     * @author Administrator
     * @date 2019/01/07
     */
    public class Singleton {
        //初始设置为null,需要时才被加载,延迟加载
        private static Singleton instance = null;
    
        //私有构造,防止被实例化
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    以上两种模式:只适合在单线程环境使用,多线程环境容易出现不同步的情况。在多线程模式下,可能产生问题。比如下面的实例

    package singleton.demo;
    
    /**
     * @author Administrator
     * @date 2019/01/07
     */
    public class Singleton {
        //初始设置为null,需要时才被加载,延迟加载
        private static Singleton instance = null;
    
        //私有构造,防止被实例化
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (instance == null) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                instance = new Singleton();
            }
            return instance;
        }
    }
    package singleton.demo;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * @author Administrator
     * @date 2019/01/07
     */
    public class Test {
        public static void main(String[] args){
            ExecutorService executorService = Executors.newCachedThreadPool();
            for(int i=0;i<5;i++){
                executorService.submit(new Runnable() {
                    public void run() {
                        System.out.println(Singleton.getInstance().hashCode());
                    }
                });
            }
            executorService.shutdown();
    
        }
    }

    执行结果:

    1369340138
    1555013046
    285003072
    270952636
    84064941

     之所以出现不同步,是因为,当多个线程执行 getInstance() 的时候,都发现instance是null,所以每个线程各自创建了一个instance

     3、使用static块实现线程安全的单例模式

    注意:以下try-catch不是模式需要的代码,这里只是为了测试多线程环境才加上的

    package singleton.demo;
    
    /**
     * @author Administrator
     * @date 2019/01/07
     */
    public class Singleton {
        //初始设置为null,需要时才被加载,延迟加载
        private static Singleton instance = null;
    
        //私有构造,防止被实例化
        private Singleton() {}
    
        static {
            instance = new Singleton();
        }
    
        public static Singleton getInstance() {
            if (instance == null) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                instance = new Singleton();
            }
            return instance;
        }
    }
    package singleton.demo;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * @author Administrator
     * @date 2019/01/07
     */
    public class Test {
        public static void main(String[] args){
            ExecutorService executorService = Executors.newCachedThreadPool();
            for(int i=0;i<5;i++){
                executorService.submit(new Runnable() {
                    public void run() {
                        System.out.println(Singleton.getInstance().hashCode());
                    }
                });
            }
            executorService.shutdown();
    
        }
    }
    2050945573
    2050945573
    2050945573
    2050945573
    2050945573
  • 相关阅读:
    编程之美:位运算应用集萃
    【总结系列】互联网服务端技术体系:高性能之缓存面面观
    【总结系列】互联网服务端技术体系:高性能之并发(Java)
    【总结系列】互联网服务端技术体系:高性能之数据库索引
    【总结系列】互联网服务端技术体系:可扩展之数据分区
    一道关于二叉树的字节面试题的思考
    python基础之range()函数和random模块
    记录下第一次参加leetcode 周赛
    几种方法实现“反转字符串”
    c# 自动更新程序
  • 原文地址:https://www.cnblogs.com/boshen-hzb/p/9076495.html
Copyright © 2011-2022 走看看