文档章节

单例模式

清尘V
 清尘V
发布于 2016/04/15 14:10
字数 1187
阅读 57
收藏 1

精选30+云产品,助力企业轻松上云!>>>

单例模式有三种:

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

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

上一篇: java 交换数据
下一篇: 抽象工厂模式
清尘V

清尘V

粉丝 41
博文 107
码字总数 47780
作品 0
青岛
程序员
私信 提问
加载中
此博客有 1 条评论,请先登录后再查看。

暂无文章

Java知识点--卫语句

在《阿里巴巴Java开发手册》中强制规定:超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现,其中卫语句即代码逻辑先考虑失败、异常、中断、退出等直接返回的情...

HLee
43分钟前
9
0
实施与扩展:何时使用? 有什么不同? - Implements vs extends: When to use? What's the difference?

问题: 请用一种易于理解的语言或一些文章的链接进行解释。 解决方案: 参考一: https://stackoom.com/question/jTkh/实施与扩展-何时使用-有什么不同 参考二: https://oldbug.net/q/jTkh/...

技术盛宴
44分钟前
3
0
剑指offer之队列中的最大值(C++/Java双重实现)

1.题目描述 请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。 若队列为空,pop_front 和 max_value 需要返回...

osc_jvzgahav
46分钟前
5
0
JAVA-过滤器和拦截器1

1、过滤器 (Filter) 过滤器的配置比较简单,直接实现 Filter 接口即可,也可以通过 @WebFilter 注解实现对特定 URL 拦截,看到 Filter 接口中定义了三个方法。 init() :该方法在容器启动初始...

osc_hinb5m98
48分钟前
21
0
模拟红包算法(基于BigDecimal、DecimalFormat、Random类)

基于BigDecimal、DecimalFormat、Random实现模拟红包算法 RedPacket 类 import java.math.BigDecimal;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Rand......

osc_ml6lx2h4
49分钟前
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部