StampedLock的使用和主要实现思想
在多线程开发中,为了控制线程同步,使用的最多的莫过于synchronized 关键字和重入锁。在JDK8中,又引入了一款新式武器StampedLock。这是一个什么东西呢?英文单词Stamp,意思是邮戳。那在这里有用什么含义呢?傻瓜,请看下面的分解。 面对临界区资源管理的问题,大体上有2套思路: 第一就是使用悲观的策略,悲观者这样认为:在每一次访问临界区的共享变量,总是有人会和我冲突,因此,每次访问我必须先锁住整个对象,完成访问后再解锁。 而与之相反的乐天派却认为,虽然临界区的共享变量会冲突,但是冲突应该是小概率事件,大部分情况下,应该不会发生,所以,我可以先访问了再说,如果等我用完了数据还没人冲突,那么我的操作就是成功;如果我使用完成后,发现有人冲突,那么我要么再重试一次,要么切换为悲观的策略。这里不难看到,重入锁以及synchronized 是一种典型的悲观策略。聪明的你一定也猜到了,StampedLock就是提供了一种乐观锁的工具,因此,它是对重入锁的一个重要的补充。 StampedLock的基本使用在StampedLock的文档中就提供了一个非常好的例子,让我们可以很快的理解StampedLock的使用。下面让我看一下这个例子,有关它的说明,都写在注释接受参数是上次锁操作返回的邮戳,如果在调用validate()之前,这个锁没有写锁申请过,那就返回true,这也表示锁保护的共享数据并没有被修改,因此之前的读取操作是肯定能保证数据完整性和一致性的。 反之,如果锁在validate()之前有写锁申请成功过,那就表示,之前的数据读取和写操作冲突了,程序需要进行重试,或者升级为悲观锁。 和重入锁的比较从上面的例子其实不难看到,就编程复杂度来说,StampedLock其实是要比重入锁复杂的多,代码也没有以前那么简洁了。 那么,我们为什么还要使用它呢?最本质的原因,就是为了提升性能!一般来说,这种乐观锁的性能要比普通的重入锁快几倍,而且随着线程数量的不断增加,性能的差距会越来越大。 简而言之,在大量并发的场景中StampedLock的性能是碾压重入锁和读写锁的。 但毕竟,世界上没有十全十美的东西,StampedLock也并非全能,它的缺点如下: 编码比较麻烦,如果使用乐观读,那么冲突的场景要应用自己处理
它是不可重入的,如果一不小心在同一个线程中调用了两次 (编辑:唐山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |