博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式的那些事
阅读量:6992 次
发布时间:2019-06-27

本文共 3577 字,大约阅读时间需要 11 分钟。

写在前面

  单例Singleton设计模式, 老生常谈的一个设计模式。但你真的用对了么? 用的姿势很重要!

1.概念解释

  单例顾名思义就是只产生一个实例对象。那怎样保证单一呢?把目标类提供给外部创建实例对象的能力收回,即构造函数设为私有,然后内部提供一个生成实例静态方法。设计成单例模式, 有各种各样的实现方式。

2.单例模式的设计

2.1 饿汉式单例

  饿汉式单例是指在方法调用前,实例就已经创建好了。

-实现代码:

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

-验证高并发下的执行情况

public class SingletonClient {    public static void main(String[] args) throws InterruptedException {        Thread[] threads = new Thread[10];        for (int i = 0; i < 10; i++) {            final Singleton instance = Singleton.getInstance();            threads[i] = new Thread(new Runnable() {                @Override                public void run() {                    System.out.println(instance.hashCode());                }            });        }        for (Thread thread : threads) {            thread.start();        }    }}
  • 结果
165827088165827088165827088165827088165827088165827088165827088165827088165827088165827088

2.2 懒汉式单例

懒汉式单例是指在方法调用获取实例时才创建实例,因为相对饿汉式显得“不急迫”,所以被叫做“懒汉模式”。

1)单线程的懒汉式单例 -- 初学者最容易犯错的写法.

public class Singleton {    private static Singleton instance = null;    private Singleton() {    }    public static Singleton getInstance() {        if (instance == null) {            try {                // 刻意模仿多线程访问下创建实例不是单一的情况                Thread.sleep(100);             } catch (InterruptedException e) {                e.printStackTrace();            }            instance = new Singleton();        }        return instance;    }}

上面创建单例在单线程下是木问题的。但在多线程访问下就会有问题啦。

如何改进呢?来,再往下看

2)线程安全的懒汉式单例.

-同步方法锁定

  同步方法效率很低, 它把真个方法都加了锁, 在高并发下, 只允许一个线程进入到该方法

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() {        try {            synchronized (Singleton.class) {                if (instance == null) {                    Thread.sleep(100);                    instance = new Singleton();                }            }        } catch (Exception e) {        }        return instance;    }}

-双检查锁机制(推荐

这种方式不仅能保证线性安全, 还能提高效率。因为volatile关键字保证多线程间的可见性;在同步块中使用二次检查,以保证其不被重复实例化。集合其二者,这种实现方式既保证了其高效性,也保证了其线程安全性。

public class Singleton {    // volatile 关键词修饰    volatile private static Singleton instance = null;    private Singleton() {    }    public static Singleton getInstance() {        try {            if (instance == null) {                synchronized (Singleton.class) {                    Thread.sleep(100);                    instance = new Singleton();                }            }        } catch (Exception e) {        }        return instance;    }}

3)使用静态内置类实现单例模式.

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

4)使用静态代码块实现单例模式

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

写在后面

转载于:https://www.cnblogs.com/chenmo-xpw/p/7056239.html

你可能感兴趣的文章
面向对象与面向过程的区别
查看>>
Python数据类型
查看>>
MySQL增删改查--之改
查看>>
linux 基础服务(一)
查看>>
《PUBG》大动作封锁3百万玩家 作弊问题严重
查看>>
网络工程师成长日记340-某邮政防火墙
查看>>
Java之品优购课程讲义_day02(4)
查看>>
Linux学习-文件管理(1)
查看>>
洞悉物联网发展1000问之什么是物联网基础设施?
查看>>
洞悉物联网发展1000问之智能加到底加什么?
查看>>
错误:26.1.0和27.1.1differ问题
查看>>
2018-05-30笔记(Linux shell基础知识)
查看>>
openStack 瓶颈测试
查看>>
学习java 想成为合格Java软件工程师所要具备哪些专业技能
查看>>
想要提高日常办公效率?这几款软件利器帮助你武装自己!
查看>>
好程序员大数据技术分享:Zookeeper集群管理与选举
查看>>
怎么找到相似Graph?DeepMind提出超越GNN的图匹配网络
查看>>
【2013年总结】思维跌宕起伏,生命颠簸曲折的一年
查看>>
Oracle管理存储架构(一)--概念
查看>>
Centos7系统下Docker ce的安装及镜像加速
查看>>