扫码关注公众号

多线程和并发之 Lock锁和原子锁
05-31
27观看
01

如何让 Java 的线程彼此同步?

1.synchronized2.volatile3.ReenreantLock4.使用局部变量实现线程同步

来自:并发和同步-锁的定义和分类
02

一般有哪几种方式降低锁的竞争程度?

我们一般有三种方式降低锁的竞争程度:1、减少锁的持有时间2、降低锁的请求频率3、使用带有协调机制的独占锁,这些机制允许更高的并发性。在某些情况下我们可以将锁分解技术进一步扩展为一组独立对象上的锁进行分解,这成为分段锁。其实说的简单一点就是:容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。比如:在ConcurrentHashMap中使用了一个包含16个锁的数组,每个锁保护所有散列桶的1/16,其中第N个散列桶由第(Nmod16)个锁来保护。假设使用合理的散列算法使关键字能够均匀的分部,那么这大约能使对锁的请求减少到越来的1/16。也正是这项技术使得ConcurrentHashMap支持多达16个并发的写入线程。

来自:并发和同步-锁的定义和分类
03

自旋锁的优点是什么?又存在哪些问题?

自旋锁的优点1、自旋锁不会使线程状态发生切换,一直处于用户态,即线程一直都是active的;不会使线程进入阻塞状态,减少了不必要的上下文切换,执行速度快2、非自旋锁在获取不到锁的时候会进入阻塞状态,从而进入内核态,当获取到锁的时候需要从内核态恢复,需要线程上下文切换。(线程被阻塞后便进入内核(Linux)调度状态,这个会导致系统在用户态与内核态之间来回切换,严重影响锁的性能)自旋锁存在的问题1、如果某个线程持有锁的时间过长,就会导致其它等待获取锁的线程进入循环等待,消耗CPU。使用不当会造成CPU使用率极高。2、上面Java实现的自旋锁不是公平的,即无法满足等待时间最长的线程优先获取锁。不公平的锁就会存在“线程饥饿”问题。

来自:并发和同步-锁的定义和分类
04

死锁产生的条件是什么?

·互斥条件:资源是独占的且排他使用,进程互斥使用资源,即任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请者等待直到资源被占有者释放。·不可剥夺条件:进程所获得的资源在未使用完毕之前,不被其他进程强行剥夺,而只能由获得该资源的进程资源释放。·请求和保持条件:进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。·循环等待条件:在发生死锁时必然存在一个进程等待队列{P1,P2,…,Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路,环路中每一个进程所占有的资源同时被另一个申请,也就是前一个进程占有后一个进程所深情地资源。

来自:并发和同步-锁的定义和分类
专栏
Lock锁的使用
观察ReentrantLock类可以发现其实现了Lock接口
csdn
Lock锁
【校招VIP】你知道Java里有多少种锁吗?(15种锁最全总结)
csdn
Java
锁的分类
【校招VIP】java 关于锁常见面试题
csdn
Java
面试题
java语言-并发和同步-锁的定义和分类
3专栏
0课程
4 试题