Java:Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好( 三 )


Hashtable和HashMap两者都有同样的方法 , 有同样的实现算法 , 唯一不同就是Hashtable中的方法使用了synchronized修饰 , 所以Hashtable的性能要比HashMap低 。
volatile关键字volatile关键字的作用在于:被volatile关键字修饰的变量的值 , 将不会被本地线程缓存 , 所有对该变量的读写都是直接操作共享内存 , 从而可以确保多个线程能正确处理该变量 。
需要注意的是 , volatile关键字可能会屏蔽虚拟机中的一些必要的优化操作 , 所以运行效率不是很高 , 因此 , 没有特别的需要 , 不要使用;即便使用 , 也要避免大量使用 。
单例模式单例模式--饿汉模式
代码如下:
单例模式--饿汉模式
单例模式--懒汉模式
代码如下:
单例模式--懒汉模式
懒汉模式存在线程不安全问题 , 在对instance对象做判断时由于并发导致出现和抢气球案例一样的问题 。 为了解决这个问题 , 使用双重检查加锁机制来解决 。

双重检查加锁机制
使用“双重检查加锁”机制实现的程序 , 既能实现线程安全 , 有能够使性能不受较大的影响 。 那么何谓“双重检查加锁”机制?其指的是:

  1. 并不是每次进入getInstance方法都需要同步 , 而是先不同步 , 进入方法后 , 先检查实例是否存在 , 如果不存在才执行同步代码块 , 这是第一重检查;

  2. 进入同步块后 , 再次检查实例是否存在 , 如果不存在 , 就在同步块中创建一个实例 , 这是第二重检查 。

这样 , 就只需要同步一次 , 减少了多次在同步情况判断所浪费的时间 。

“双重检查加锁”机制的实现需要volatile关键字的配合使用 , 且Java 版本需要在Java 5及以上 , 虽然该机制可实现线程安全的单例模式 , 也要根据实际情况酌情使用 , 不宜大量推广使用 。

使用“双重检查加锁”机制改写后的懒汉模式 , 代码如下:
使用“双重检查加锁”机制改写后的懒汉模式
Lock 锁机制
Lock 接口
java.util.concurrent.locks包提供了Lock接口 , Lock锁机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作 , 而且功能比synchronized代码块和synchronized方法更加强大 。

官方的提供了参考价值很大的demo , 能够很好的提现Lock机制的功能:
Lock 机制的官方demo
使用Lock 机制改写的抢气球案例代码如下所示:

使用Lock 机制改写的抢气球案例
改写后 , 案例运行正常 。

完结 。 老夫虽不正经 , 但老夫一身的才华!关注我 , 获取更多编程科技知识 。


推荐阅读