可重入锁 与 不可重入锁
原理就是当前线程访问的资源的时候,可以用获取线程名判断是否是同一个线程,如果是的话就可以访问其他资源,同时计数器加一。不是的话wait等待。
当退出时,计数器减一。如果计数器为零,代表执行完成,使用notify唤醒即可。
也可以使用JDK已经封装好的类 ReentrantLock
可重入锁代码
package mobai.others;
/**
* 模拟可重入锁 锁可以延续使用 + 计数器
* @author MAIBENBEN
*
*/
public class LockTest03 {
ReLock lock = new ReLock();
public void a() throws InterruptedException {
lock.lock();
System.out.println(lock.getHoldCount());
doSomething();
lock.unlock();
System.out.println(lock.getHoldCount());
}
//可重入
public void doSomething() throws InterruptedException {
lock.lock();
System.out.println(lock.getHoldCount());
System.out.println("-*-*-*-*-*-");
lock.unlock();
System.out.println(lock.getHoldCount());
}
public static void main(String[] args) {
LockTest03 test = new LockTest03();
try {
test.a();
Thread.sleep(1000);
System.out.println(test.lock.getHoldCount());
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
//可重入锁
class ReLock{
//是否使用
private boolean isLock = false;
Thread lockedBy = null;//存储线程
private int holdCount = 0;
public int getHoldCount() {
return holdCount;
}
public void setHoldCount(int holdCount) {
this.holdCount = holdCount;
}
//使用锁
public synchronized void lock() throws InterruptedException {
Thread t = Thread.currentThread();
while(isLock&&lockedBy!=t) {
wait();
}
isLock = true;
lockedBy = t;
holdCount++;
}
//释放锁
public synchronized void unlock(){
if(Thread.currentThread()==lockedBy) {
holdCount--;
}
if(holdCount==0) {
isLock = false;
notify();
lockedBy = null;
}
}
}