单例模式的应用

概述

单例模式是一个类,主要作用是在全局模式下生成唯一的一个类,为此在业务概念上,如果有些数据在系统中只应保存一份,那就比较适合设计为单例类,比如日志记录类,Logger,或是全局下唯一递增ID号码生成器

需求

有一个单例模型设计出来的唯一ID生成器,我们需要在高并发环境下测试这个唯一ID生成器是否真能生成唯一的ID

public class IdGeneratorScjc {
     
    //创建你需要的类
    private AtomicLong id = new AtomicLong();
    private static IdGeneratorScjc instance;
    //构造函数私有化
    private IdGeneratorScjc(){
     
    }
    public static IdGeneratorScjc getInstance(){
     
        if (instance==null){
     
            synchronized (IdGeneratorScjc.class){
     
                if (instance==null){
     
                    instance = new IdGeneratorScjc();
                }
            }
        }
        return instance;
    }
    public long getId(){
     
        return id.getAndIncrement();
    }
}

实现

我们想到的是多线程模拟下去模拟高并发的环境,那么就需要一个多线程类,这个线程类能够产生足够多的线程,去访问Controller方法,我们在控制台观察id,是否重复,不重复则说明单例模式起作用了

多线程类

public class ThreadTest{
     

    //java模拟多线程高并发测试程序
    static int count = 0;
    int threadNum = 4;
    int clientNum = 20000;

    public static void main(String[] args) {
     
        new ThreadTest().run();
    }

    public void run() {
     

        // 建立ExecutorService线程池,threadNum个线程可以同时访问
        ExecutorService exec = Executors.newFixedThreadPool(threadNum);
        // 模拟clientNum个客户端访问
        final CountDownLatch doneSignal = new CountDownLatch(clientNum);

        for (int i = 0; i < clientNum; i++) {
     
            Runnable run = new Runnable() {
     
                public void run() {
     
                    try {
     
                        URL url = new URL("http://localhost:8089/idGenerator/getId");
                        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                        int contentLength = urlConnection.getContentLength();
                        Thread.sleep(1000);
                    } catch (Exception e) {
     
                        e.printStackTrace();
                    }
                    doneSignal.countDown();// 每调用一次countDown()方法,计数器减1
                }
            };
            exec.execute(run);
        }
    }

}

controller类

@RequestMapping("getId")
    public void getId(){
     

        long id = IdGeneratorScjc.getInstance().getId();
        System.out.println("id:"+id);
    }

结果,没有问题,算是单例模式的一个简单应用吧,多线程真滴好用
单例模式的应用_第1张图片

你可能感兴趣的:(设计模式)