静态内部类实现单例(单号生成)

单例适用场景:

1. 需要生成唯一序列的环境

2. 需要频繁实例化然后销毁的对象。

3. 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。

4. 方便资源相互通信的环境

下面就了解一下静态内部类模式:

     通过静态内部类实现单例的实现单号的生成,实际就是把类似把对象私有化(私有化构造器),让别人无法调用它的对象,只能通过调用 getInstance 静态方法返回该类对象。而getInstance静态方法判断如果有该对象存在就返回该对象,如果没有再创建一个新对象返回,所以就达到返回的对象是同一个的目的或者没有就创建一个新对象,后续的调用就是返回同一个对象;我在getInstance方法里面放了一个同步但它只是同步返回对象,防止同时生成两个新对象;如果不明白可以看下面是如何调用和证明该对象是唯一的;

 

在类里面创建两个线程,模仿两个人同时调用会不会出现问题:

    这里输出静态的单号生成方法,并且输出调用的线程名称;

下面来看一下部分运行效果;

可以看到对象哈希是同一个;第一第二行都生成了哈希对象为什么呢?两线程调用对象比较快,导致第一个线程还没有执行run方法,第二个线程就去获取对象,然后就出现运行出两个对象哈希值;

代码:

public class PrimaryGenerater {
       private static String number=null;    
       private static PrimaryGenerater primaryGenerater = null;
       //私有化构造器
        private PrimaryGenerater() {
        }
        /**
         * 取得PrimaryGenerater的单例实现
         *
         * @return
         */
        public static PrimaryGenerater getInstance() {
            if (primaryGenerater == null) {
                //synchronized同步锁
                synchronized (PrimaryGenerater.class) {
                    if (primaryGenerater == null) {
                        primaryGenerater = new PrimaryGenerater();
                    }
                }
            }
            System.out.println("对象哈希值:    "+primaryGenerater.hashCode());
            return primaryGenerater;//返回同一对象
        }
        /**
         *  生成下一个编号
         * @param str 生成的编号前缀
         */
        public synchronized String generaterNextNumber(String str) {
            String finalNumber = null;
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");//设置日期格式
            if (!Tools.isNotNull(number)) {
                number = "00000";// 第一次初始化编号
            }
            DecimalFormat df = new DecimalFormat("00000");//定义格式
            finalNumber = str+dateFormat.format(date)+ df.format(1 + Integer.parseInt(number));
            number=df.format(1 + Integer.parseInt(number));
            return finalNumber;
        }

        public static void main(String[] args) {
            MyThread1  thread1=new MyThread1();
            MyThread1  thread2=new MyThread1();
            thread1.start();
            thread2.start();
        }
}

class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("静态内部类:"+PrimaryGenerater.getInstance().generaterNextNumber("GD")+"   "+Thread.currentThread().getName());
            System.out.println("静态内部类:"+PrimaryGenerater.getInstance().generaterNextNumber("GD")+"   "+Thread.currentThread().getName());
            System.out.println("静态内部类:"+PrimaryGenerater.getInstance().generaterNextNumber("GD")+"   "+Thread.currentThread().getName());
            for (int j = 0; j < 3; j++) {
                System.out.println("静态内部类:"+PrimaryGenerater.getInstance().generaterNextNumber("GD")+"    "+Thread.currentThread().getName());
                System.out.println("静态内部类:"+PrimaryGenerater.getInstance().generaterNextNumber("GD")+"    "+Thread.currentThread().getName());
                System.out.println("静态内部类:"+PrimaryGenerater.getInstance().generaterNextNumber("GD")+"    "+Thread.currentThread().getName());
            }
        }
    }
}

 

     如有什么不当请多多指教;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值