操作系统中的锁
开发过程中,最常?的就是互斥锁的了,互斥锁加锁失败时,会?「线程切换」来应对,当加锁失败的线
程再次加锁成功后的这?过程,会有两次线程上下?切换的成本,性能损耗?较?。
如果我们明确知道被锁住的代码的执?时间很短,那我们应该选择开销?较?的?旋锁,因为?旋锁加锁
失败时,并不会主动产?线程切换,?是?直忙等待,直到获取到锁,那么如果被锁住的代码执?时间很
短,那这个忙等待的时间相对应也很短。
如果能区分读操作和写操作的场景,那读写锁就更合适了,它允许多个读线程可以同时持有读锁,提?了
读的并发性。根据偏袒读?还是写?,可以分为读优先锁和写优先锁,读优先锁并发性很强,但是写线程
会被饿死,?写优先锁会优先服务写线程,读线程也可能会被饿死,那为了避免饥饿的问题,于是就有了
公平读写锁,它是?队列把请求锁的线程排队,并保证先?先出的原则来对线程加锁,这样便保证了某种
线程不会被饿死,通?性也更好点。
互斥锁和?旋锁都是最基本的锁,读写锁可以根据场景来选择这两种锁其中的?个进?实现。
另外,互斥锁、?旋锁、读写锁都属于悲观锁,悲观锁认为并发访问共享资源时,冲突概率可能?常?,
所以在访问共享资源前,都需要先加锁。
相反的,如果并发访问共享资源时,冲突概率?常低的话,就可以使?乐观锁,它的?作?式是,在访问
共享资源时,不?先加锁,修改完共享资源后,再验证这段时间内有没有发?冲突,如果没有其他线程在
修改资源,那么操作完成,如果发现有其他线程已经修改过这个资源,就放弃本次操作。
但是,?旦冲突概率上升,就不适合使?乐观锁了,因为它解决冲突的重试成本?常?。
不管使?的哪种锁,我们的加锁的代码范围应该尽可能的?,也就是加锁的粒度要?,这样执?速度会?
较快。再来,使?上了合适的锁,就会快上加快了。