1. 可重入锁
如synchronized和ReentrantLock都是可重入锁,可重入性实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。当一个线程执行到某个synchronized方法时,如method1方法,而在method1中会调用另一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行method2。如递归方法的调用,如果递归方法被synchronized修饰,如果synchronized不是可重入的,这样就会出现自己等待自己释放锁的情况。
2. 可中断锁
就是可以响应中断的锁,在Java中,synchronized是不可中断锁,而Lock是可中断锁。
如果某一线程A正在执行锁中的代码,另一线程B正在等待获取该锁,可能由于等待时间过长,线程B不想等待了,想先处理其他的事情,我们可以让它中断自己或在别的线程中中断它,这就是可中断锁。
3. 公平锁
公平锁尽量以请求锁的顺序来获取锁,如多个线程同时在等待一个锁,当这个锁被释放后,等待时间最长的线程(即最先请求锁的线程)会获得锁,这就是公平锁。
非公平锁无法保证锁的获取是按照锁的顺序进行的。这样就可能导致某个或者一些线程长时间或永远获取不到锁。
在Java中,synchronized就是非公平锁,他无法保证等待的线程获取锁的顺序。对于ReentrantLock默认情况下是非公平锁,但是可以设置为公平锁。
//实例化ReentrantLock时参数设置为true:即为公平锁
ReentrantLock lock = new ReentrantLock(true);
4. 读写锁
读写锁对一个资源(如文件)的访问分成了2个锁,一个读锁和一个写锁。
如果一个线程已经申请了读锁,则其他的线程也可以申请读锁,但申请写锁会被阻塞,直到读锁被释放;如果一个线程已经申请了写锁,则其他线程申请读锁或写锁都会被阻塞,直到该写锁被释放。就是说读锁可以和读锁共存,而写锁和任何锁都不能共存。