【问题标题】:Performance test:singleton class with and without double check locking性能测试:带和不带双重检查锁定的单例类
【发布时间】:2014-05-08 12:03:20
【问题描述】:

我有两个单例类的实现

public class Test2 {

private static Test2 _instance=new Test2();

private Test2(){

}

public static synchronized Test2 getInstance(){

    if(_instance == null){          
        _instance = new Test2();
    }
    return _instance;
}
}

还有:

public class TestSingleton {

private static TestSingleton _instance=new TestSingleton();

private TestSingleton(){

}

public static TestSingleton getInstance(){
    if (_instance == null) {
        synchronized (TestSingleton.class) {

            if (_instance == null) {
        _instance = new TestSingleton();
            }
        }
    }
    return _instance;
}

我想根据所用时间参数化我的发现,我所做的是:

Callable<Long> task = new Callable<Long>() {
        @Override
        public Long call() throws Exception {
            long start = System.nanoTime();
            **TestSingleton.getInstance();**
            long end = System.nanoTime();
            return end - start;
        }
    };

    for (int i = 0; i < 100000; i++) {
        futList.add(es1.submit(task));
    }

    for (Future<Long> fut : futList) {
        try {
            totalTime1.getAndAdd(fut.get());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    System.out.println("Time taken by S1   " + totalTime1.get());
            .
            .
            ExecutorService es2 = Executors.newFixedThreadPool(threadpool);

    Callable<Long> task1 = new Callable<Long>() {
        @Override
        public Long call() throws Exception {
            long start = System.nanoTime();
            Test2.getInstance();
            long end = System.nanoTime();
            return end - start;
        }
    };

    for (int i = 0; i < 100000; i++) {
        futList1.add(es2.submit(task1));
    }

    for (Future<Long> fut : futList1) {
        try {
            totalTime2.getAndAdd(fut.get());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    System.out.println("Time taken by S2   " + totalTime2.get());

我得到的结果是:

S1 4636498 所用时间 S2 5127865所用时间

第一个问题这是正确的方法吗?其次,即使我在call() 中都注释了getinstances 方法,我也会得到两个相同块的不同执行时间:

S1 1506640 所用时间 S2 2156172所用时间

【问题讨论】:

    标签: performance testing singleton executorservice double-checked-locking


    【解决方案1】:

    不要测量每次执行并总结时间,单个测量会有太多的不准确性。相反,获取开始时间,执行 100000 次,获取结束时间。此外,在开始测量之前执行几 1000 次以避免因启动成本而出现偏差。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-08
      • 2016-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多