1、可重入锁
可重复递归调用的锁,在外层获得锁后内层可以直接使用(同一对象)就叫可重入锁。synchronized和ReentrantLock都是可重入锁。
synchronized实例:
public class LockTest { private synchronized void get(){ System.out.println("get test"); set(); } private synchronized void set(){ System.out.println("set test"); } public static void main(String[] args) { LockTest lockTest = new LockTest(); lockTest.get(); } }
输出结果为:
get test set test
假如synchronized不具有可重入性,主线程在执行get方法时获取到了锁,内部执行set方法又去获取锁,此时并没有释放锁因此也就获取不到锁就会死锁。synchronized具备可重入性就避免死锁的发生。
下面看看ReentrantLock可重入性的实现:
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
在多次去获取锁时,通过getExclusiveOwnerThread()获取当前占有锁的线程,如果和当前线程一致则计数器加一并返回true。
2、可中断锁
可以响应中断的锁就是可中断锁。synchronized不是可中断锁,而Lock是可中断锁。
如果a线程长期占有锁,b线程等待一段时间后不想等待了就可以通过Lock接口的tryLock(long time, TimeUnit unit)和lockInterruptibly()方式中断等待去干别的事。而synchronized则需要一致等待下去。
3、公平锁
synchronized是非公平锁。ReentrantLock和ReentrantReadWriteLock默认情况下是非公平的,可以通过设置为公平锁。公平锁就是尽量以请求锁的顺序来获取锁。
ReentrantLock公平锁实例:
public class LockTest { private ReentrantLock fairLock = new ReentrantLock(true); private void print(){ try { fairLock.lock(); System.out.println("线程:"+Thread.currentThread().getName()+"获取锁"); } finally { System.out.println("线程:"+Thread.currentThread().getName()+"释放锁"); fairLock.unlock(); } } public static void main(String[] args) { LockTest lockTest = new LockTest(); for(int i=0;i<10;i++){ new Thread(new Runnable() { @Override public void run() { lockTest.print(); } }).start(); } } }
输出结果:
线程:Thread-0获取锁 线程:Thread-0释放锁 线程:Thread-2获取锁 线程:Thread-2释放锁 线程:Thread-4获取锁 线程:Thread-4释放锁 线程:Thread-6获取锁 线程:Thread-6释放锁 线程:Thread-8获取锁 线程:Thread-8释放锁 线程:Thread-1获取锁 线程:Thread-1释放锁 线程:Thread-5获取锁 线程:Thread-5释放锁 线程:Thread-3获取锁 线程:Thread-3释放锁 线程:Thread-9获取锁 线程:Thread-9释放锁 线程:Thread-7获取锁 线程:Thread-7释放锁
可以看到只是尽量保持公平
转载请注明:Terry's blog » java中锁概念理解:可重入锁、可中断锁、公平锁