Lock
Lock比传统线程模型中的synchronized方式更加面向对象。说白了Lock就是个对象,两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。
lock提供的方法
相比于synchronized来说更加的灵活了,提供了尝试获取锁,超时获取锁等方法。
lock() : 获取锁,调用该方法的线程会获得锁,
lockInterruptibly():可中断获取锁。
tryLock():能够尝试获取锁
unlock():释放锁。
ReentrantLock
锁的可重入:
简单地讲就是:“同一个线程对于已经获得到的锁,可以多次继续申请到该 锁的使用权”。而synchronized关键字隐式的支持重进入,比如一个synchronized 修饰的递归方法,在方法执行时,执行线程在获取了锁之后仍能连续多次地获得 该锁。ReentrantLock 在调用 lock()方法时,已经获取到锁的线程,能够再次调用 lock()方法获取锁而不被阻塞。
公平和非公平锁:
如果在时间上,先对锁进行获取的请求一定先被满足,那么这个锁是公平的, 反之,是不公平的。公平的获取锁,也就是等待时间最长的线程最优先获取锁, 也可以说锁获取是顺序的。 ReentrantLock 提供了一个构造函数,能够控制锁是 否是公平的。事实上,公平的锁机制往往没有非公平的效率高。
读写锁 ReentrantReadWriteLock
上面提到的锁,基本都是排它锁,这些锁在同一 时刻只允许一个线程进行访问。
而读写锁在同一时刻可以允许多个读线程访问, 但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁维护了一对 锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁 有了很大提升。
读锁与写锁之间,读锁与读锁间并不互斥,写锁与其他锁互斥。
所以应用在读多写少的场景中,能够提升不少的效率