单例模式的标准写法、注意事项、作用及测试

Trinea 发布于 2013/09/09 21:01
阅读 2K+
收藏 20

最新最准确内容建议直接访问原文:单例模式

 

主要介绍单例模式的标准写法、注意事项、作用、测试,以Java语言为例,下面代码是目前见过最好的写法:

public class Singleton { private static volatile Singleton instance = null; // private constructor suppresses private Singleton(){
    } public static Singleton getInstance() { // if already inited, no need to get lock everytime if (instance == null) { synchronized (Singleton.class) { if (instance == null) {
                    instance = new Singleton();
                }
            }
        } return instance;
    }
}

1、需要注意的点

其中需要注意的点主要有三点
(1) 私有化构造函数
(2) 定义静态的Singleton instance对象和getInstance()方法
(3) getInstance()方法中需要使用同步锁synchronized (Singleton.class)防止多线程同时进入造成instance被多次实例化
可以看到上面在synchronized (Singleton.class)外又添加了一层if,这是为了在instance已经实例化后下次进入不必执行synchronized (Singleton.class)获取对象锁,从而提高性能。

Ps: 也有实现使用的是private static Object    obj      = new Object();加上synchronized(obj),实际没有必要多创建一个对象。synchronized(X.class) is used to make sure that there is exactly one Thread in the block.

 

2、单例的作用
单例主要有两个作用
(1) 保持程序运行过程中该类始终只存在一个示例
(2) 对于new性能消耗较大的类,只实例化一次可以提高性能

 

3、单例模式测试

单例模式可以使用多线程并发进行测试,代码如下:

public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(1); int threadCount = 1000; for (int i = 0; i < threadCount; i++) { new Thread() {

            @Override public void run() { try { // all thread to wait  latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } // test get instance  System.out.println(Singleton.getInstance().hashCode());
            }
        }.start();
    } // release lock, let all thread excute Singleton.getInstance() at the same time  latch.countDown();
}

其中CountDownLatch latch为闭锁,所有线程中都用latch.await();等待锁释放,待所有线程初始化完成使用latch.countDown();释放锁,从而达到线程并发执行Singleton.getInstance()的效果

 

你可能还感兴趣:

Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)

Android ImageCache图片缓存

Android性能优化专题

加载中
0
重度恐高症
重度恐高症
请参考网上文章《单例的7种写法》
0
liunkor
liunkor
学习了
0
francis-x
francis-x

也有实现使用的是private static Object    obj      = new Object();加上synchronized(obj),实际没有必要多创建一个对象。synchronized(X.class) is used to make sure that there is exactly one Thread in the block.

----

严格的来说,使用对象锁要比类锁要轻量级的多,高并发下,明显是对象锁效率更高,所以从性能上考量第一种算不上最优,只有在能保证每一调用时没有太多的线程共同访问getInstance才能相对较优。但估计影响也很小,所以就无所谓了。

另一方面这种方式均没有保证反序列化后仍然是单例的,不能运用在很复杂的场景。

其实单例有好多种写法,之所以有这么多写法存在,也正是因为它们适用于不同的场景。一般情况下饿汉模式够用了。

另外,双重检查锁定在JVM上是一种不安全的编程模型,不推荐使用:

http://www.ibm.com/developerworks/cn/java/j-dcl.html

这边有其它单例模式的参考:

http://cantellow.iteye.com/blog/838473

0
OSC首席键客
OSC首席键客

引用来自“潮汐猎人”的答案

请参考网上文章《单例的7种写法》
有七种写法啊!……我擦!
0
悟方向
悟方向
写个枚举最简单 
返回顶部
顶部