详解Java 常见的锁

 

自己有段时间没有写博客了,实在不好意思,最近工作确实有点忙。最近工作有使用到Java多线程同步锁相关知识,

以下为自己做的一个小总结,以便与大家互相学习,哈哈。

1.独享锁

也叫互斥锁,是指该锁一次只能被一个线程所持有。常见的有ReentrantLock、ReadWriteLock。

2.共享锁

是指该锁可被多个线程所持有。常见的有CountDownLatch。

3.乐观锁

顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

乐观锁适用于多读的应用类型,乐观锁在Java中是通过使用无锁编程来实现,最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。

CAS全称 Compare And Swap(比较与交换),是一种无锁算法。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。java.util.concurrent包中的原子类就是通过CAS来实现了乐观锁。

4、悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。

典型的悲观锁就是Java的同步synchronized关键字。

5.公平锁

就是很公平,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己。

公平锁的优点是等待锁的线程不会饿死。缺点是整体吞吐效率相对非公平锁要低,等待队列中除第一个线程以外的所有线程都会阻塞,CPU唤醒阻塞线程的开销比非公平锁大。

以下为公平锁测试样例:

代码:

详解Java 常见的锁_第1张图片

运行结果:

详解Java 常见的锁_第2张图片

从上面可以看出,使用公平锁可以让线程有序的执行。

6.非公平锁

上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁那种方式。

非公平锁的优点是可以减少唤起线程的开销,整体的吞吐效率高,因为线程有几率不阻塞直接获得锁,CPU不必唤醒所有线程。缺点是处于等待队列中的线程可能会饿死,或者等很久才会获得锁。

以下为非公平锁测试样例:

代码:

详解Java 常见的锁_第3张图片

运行结果:

详解Java 常见的锁_第4张图片

从上图可以看出线程执行时是无序的。

好的,本次分享到此结束

 

更多精彩技术分享请浏览本人博客:https://blog.csdn.net/wohiusdashi

你可能感兴趣的:(java)