文档章节

单例模式

清尘V
 清尘V
发布于 2016/04/15 14:10
字数 1187
阅读 36
收藏 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
粉丝 42
博文 107
码字总数 47780
作品 0
青岛
程序员
加载中

评论(1)

TryIT1993
TryIT1993

暂无文章

Ubuntu18.04 显卡GF-940MX安装NVIDIA-390.77

解决办法: 下面就给大家一个正确的姿势在Ubuntu上安装Nvidia驱动: (a)首先去N卡官网下载自己显卡对应的驱动:www.geforce.cn/drivers (b)下载后好放在英文路径的目录下,怎么简单怎么来...

AI_SKI
今天
0
0
深夜胡思乱想

魔兽世界 最近魔兽世界出了新版本, 周末两天升到了满级,比之前的版本体验好很多,做任务不用抢怪了,不用组队打怪也是共享拾取的。技能简化了很多,哪个亮按哪个。 运维 服务器 产品 之间的...

Firxiao
今天
0
0
MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
今天
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
2
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部