java--锁机制

1 公平锁和非公平锁

公平锁是指多个线程按照中请锁的顺序来获取锁,类似排队打饭,先来后到。
非公平锁是指多个线程获取锁的顺序并不是按照中请锁的顺序,有可能后中请的线程比先申请的线程优先获取锁
在高并发的情况下,有可能会造成优先级反转或者饥饿现象

公平锁/非公平锁
并发包中ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁或非公平锁,默认是非公平锁
关于两者区别:
公平锁:Threads acquire a fair lock in the order in which they requested it
公平锁,就是很公平,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己
非公平锁: a nonfair lock permits barging: threads requesting a lock can jump ahead of the queue of waiting threads if the lockhappens to be available when it is requested.
非公平锁比较粗鲁,上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁那种方式。

Java ReentrantLock而言,

通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。
对于Synchronized而言,也是一种非公平锁

2.可重入锁(递归锁)

指的是同一线程外层函数获得锁之后﹐内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁
也即是说,线程可以进入任何一个它已经拥有的锁所同步着的代码块。I
ReentrantLock/Synchronized就是一个典型的可重入锁
可重入锁最大的作用是避免死锁

代码证明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 自旋锁

是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU

4 独占锁(写锁)/ 共享锁(读锁)/ 互斥锁

独占锁:指该锁一次只能被一个线程所持有。对ReentrantLock和Synchronized而言都是独占锁
共享锁:指该锁可被多个线程所持有。
对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁。
读锁的共享锁可保证并发读是非常高效的,读写,写读,写写的过程是互斥的。
写操作:原子+独占,整个过程必须是一个完整的统一体,中间不许被分割,被打断
代码证明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
改进方法,加读写锁
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5 CountDownLatch

让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),
当计数器的值变为零时,因调用await方法被阻塞的线程会被唤醒,继续执行。

在这里插入图片描述
在这里插入图片描述
解决方案:
在这里插入图片描述在这里插入图片描述

6 CyclicBarrier

CyclicBarrier的字面意思是可循环(Cyclic)使用的屏障( Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过cyclicBarrier的await()方法。
在这里插入图片描述

在这里插入图片描述

7 Semaphore

信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/delete_bug/article/details/119168433