单例模式的设计与实现,及性能测试

来源:互联网 发布:网络兼职有哪些 编辑:程序博客网 时间:2024/05/16 16:21

单例模式在实际应用中使用非常广泛,比如日志写入,单例模式可以避免错误,数据库连接可以避免锁死,用例执行可以避免重复调用。

先是枚举实现法:

public enum Singleton01 {INSTANCE;public void operator() {System.out.println("Operator");}}

再是内部类实现法:

public class Singleton02 {private static class Module {private static final Singleton02 instance = new Singleton02();}private Singleton02() {;}public static Singleton02 getInstance() {return Module.instance;}}

再是饿汉式:

public class Singleton03 {private static final Singleton03 instance = new Singleton03();private Singleton03() {}public static Singleton03 getInstance() {return instance;}}

再是懒汉式:

public class Singleton04 {private static Singleton04 instance;private Singleton04() {}public synchronized static Singleton04 getInstance() {if (instance == null) {instance = new Singleton04();}return instance;}}

下面是测试程序:

import java.util.concurrent.CountDownLatch;public class Client2 {private static int threadCount = 10;private static long jobCountPerThread = 1000000L;public static void main(String[] args) throws InterruptedException {testEnum();testInnerClass();testHungeryClass();testLazyClass();}public static void testEnum() throws InterruptedException {long startTime = System.currentTimeMillis();CountDownLatch countDownLatch = new CountDownLatch(threadCount);for (int i = 0; i < threadCount; i++) {new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < jobCountPerThread; i++) {Singleton01 s1 = Singleton01.INSTANCE;}countDownLatch.countDown();}}).start();}countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println("枚举单例模式总消耗时间:" + (endTime - startTime) + "毫秒");}public static void testInnerClass() throws InterruptedException {long startTime = System.currentTimeMillis();CountDownLatch countDownLatch = new CountDownLatch(threadCount);for (int i = 0; i < threadCount; i++) {new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < jobCountPerThread; i++) {Singleton02 s1 = Singleton02.getInstance();}countDownLatch.countDown();}}).start();}countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println("内部类单例模式总消耗时间:" + (endTime - startTime) + "毫秒");}public static void testHungeryClass() throws InterruptedException {long startTime = System.currentTimeMillis();CountDownLatch countDownLatch = new CountDownLatch(threadCount);for (int i = 0; i < threadCount; i++) {new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < jobCountPerThread; i++) {Singleton03 s1 = Singleton03.getInstance();}countDownLatch.countDown();}}).start();}countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println("饿汉式单例模式总消耗时间:" + (endTime - startTime) + "毫秒");}public static void testLazyClass() throws InterruptedException {long startTime = System.currentTimeMillis();CountDownLatch countDownLatch = new CountDownLatch(threadCount);for (int i = 0; i < threadCount; i++) {new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < jobCountPerThread; i++) {Singleton04 s1 = Singleton04.getInstance();}countDownLatch.countDown();}}).start();}countDownLatch.await();long endTime = System.currentTimeMillis();System.out.println("懒汉式单例模式总消耗时间:" + (endTime - startTime) + "毫秒");}}

最后就很简单了,运行起来,可以看到各个不同的模式的效率:





由图上很简单可以看出,各自不同的特点,除了懒汉式,其它几种效率都不错,但是饿汉式因为不是延迟加载,所以某些场合下不适合,可能会造成开销增加,懒汉式支持延迟加载,但是因为线程安全问题,所以效率下降比较严重,考虑综合因素,结论是枚举类型是线程安全效率又高的,同时是非延迟加载的,内部类是支持延迟加载的,也是线程安全的,而且性能也不错。


0 0