文档章节

单例模式

清尘V
 清尘V
发布于 2016/04/15 14:10
字数 1187
阅读 36
收藏 1
点赞 1
评论 1

单例模式有三种:

  • 饿汉模式:提前初始化好对象,需要的时候直接调用

package com.whereta.singleton;

/**
 * Vincent 创建于 2016/4/15.
 * 该模式是提前初始化好对象,调用的时候直接返回即可
 */
public class SingletonClass1 {
    //一定要将默认的构造函数设为私有,不能实例化
    private SingletonClass1() {

    }

    private static SingletonClass1 instance = new SingletonClass1();

    public static SingletonClass1 getInstance() {
        return instance;
    }

    public void test(){
        System.out.println("我是:"+this);
    }




}

  • 懒汉模式-双重检查加锁:在调用的时候检查对象是否实例化,如果没有实例化则实例化返回

package com.whereta.singleton;

/**
 * Vincent 创建于 2016/4/15.
 * 该模式是懒汉模式,在具体使用的时候初始化。采用双重检查加锁方式保证线程安全,
 */
public class SingletonClass2 {
    //一定要将默认的构造函数设为私有,不能实例化
    private SingletonClass2() {

    }

    private static SingletonClass2 instance = null;

    public static SingletonClass2 getInstance() {

        if (instance == null) {
            //如果为空,加锁开始初始化
            synchronized (SingletonClass2.class) {
                SingletonClass2 temp = instance;
                if (temp == null) {
                    //此处保存对象创建成功之后再返回,如果不添加temp,则会出现问题:
                    // 当instance先分配内存空间,未完成数据设置,此时instance不为null,如果有新的线程进入请求,直接返回instance,由于没有数据报错
                    synchronized (SingletonClass2.class) {
                        temp = new SingletonClass2();
                    }
                    instance = temp;
                }
            }
        }
        return instance;
    }

    public void test() {
        System.out.println("我是:" + this);
    }


}

  • 懒汉模式-内部类


  • package com.whereta.singleton;
    
    /**
     * Vincent 创建于 2016/4/15.
     * 该模式是懒汉模式,通过内部类实现线程安全,只有在调用内部类的时候才会加载实例
     */
    public class SingletonClass3 {
        //一定要将默认的构造函数设为私有,不能实例化
        private SingletonClass3() {
    
        }
    
        private static class StaticSingletonClass3 {
            private static SingletonClass3 intance = new SingletonClass3();
        }
    
        private static SingletonClass3 instance = null;
    
        public static SingletonClass3 getInstance() {
            return StaticSingletonClass3.intance;
        }
    
        public void test() {
            System.out.println("我是:" + this);
        }
    
    
    }

测试:

package com.whereta.singleton;

import org.freebencher.FbJobResult;
import org.freebencher.FbTarget;
import org.freebencher.Freebencher;

/**
 * Vincent 创建于 2016/4/15.
 */
public class Main {
    public static void main(String[] args) {

        FbJobResult result = Freebencher.benchmark(new FbTarget() { //the behavior
                                                       public boolean invoke() {
                                                           SingletonClass1 singletonClass1 = SingletonClass1.getInstance();
                                                           singletonClass1.test();

                                                           return true;
                                                       }
                                                   }, 20, // concurrency,
                10 // number of tests to run
        );

        System.out.println(result.report());

    }
}

结果:

Connected to the target VM, address: '127.0.0.1:62908', transport: 'socket'
Test started.
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
Awaiting termination...
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
我是:com.whereta.singleton.SingletonClass2@1aa0e220
100/100 are done
Test completed.
Concurrency:             50
Time taken for tests:    31ms
Successful tests:        100
Failed tests:            0
Tests per second:        3225.8064516129034
Mean time per test:      0.98ms
Percentage of the test finished within a certain time (ms)
50%:                     1
60%:                     1
70%:                     1
80%:                     2
90%:                     3
95%:                     3
98%:                     4
99%:                     4
100%:                    4

Disconnected from the target VM, address: '127.0.0.1:62908', transport: 'socket'

Process finished with exit code 0

通过输出:所有对象都是相同的,也就是只有一个实例。

以上三种方式都是线程安全的,可以放心在多线程环境下使用

  • 双重加锁方式代码比较繁琐,不推荐使用,并且在初始化的时候会加锁,一定程度影响效率

  • 饿汉模式是在程序启动的时候就初始化完成,无法是否使用就一直存在,看需求选择是否使用该方式

  • 内部类方式就保证了线程安全,也是一种懒加载模式,代码也比较简洁,推荐



个人博客:http://www.whereta.com

© 著作权归作者所有

共有 人打赏支持
清尘V
粉丝 43
博文 107
码字总数 47780
作品 0
青岛
程序员
加载中

评论(1)

TryIT1993
TryIT1993

暂无相关文章

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 1

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

CentOS开机启动subversion

建立自启动脚本: vim /etc/init.d/subversion 输入如下内容: #!/bin/bash## subversion startup script for the server## chkconfig: 2345 90 10# description: start the subve......

随风而飘 ⋅ 昨天 ⋅ 0

Nginx + uwsgi @ubuntu

uwsgi 安装 sudo apt-get install python3-pip # 注意 ubuntu python3默认没有安装pippython3 -m pip install uwsgi 代码(test.py) def application(env, start_response): start_res......

袁祾 ⋅ 昨天 ⋅ 0

版本控制工具

CSV , SVN , GIT ,VSS

颖伙虫 ⋅ 昨天 ⋅ 0

【2018.06.19学习笔记】【linux高级知识 13.1-13.3】

13.1 设置更改root密码 13.2 连接mysql 13.3 mysql常用命令

lgsxp ⋅ 昨天 ⋅ 0

LVM

LVM: 硬盘划分分区成物理卷->物理卷组成卷组->卷组划分逻辑分区。 1.磁盘分区: fdisk /dev/sdb 划分几个主分区 输入t更改每个分区类型为8e(LVM) 使用partprobe生成分区的文件:如/dev/sd...

ZHENG-JY ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部