版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_33641359/article/details/87929232
说到可重入锁默认提到的就是Reentrantlock,可重入的概念就是,当前线程可以多次获得一个锁,这样主要是解决了死锁问题。
如果没有可重入锁,当一个线程递归获得当前锁的时候,会由于锁没有释放而导致死锁,jdk基于AQS实现,主要是有个 state变量,如果是当前线程获得锁,就自增一次,释放锁就是给这个state递减,减到零就释放这个锁。这篇文章只实现非公平的可重入锁,没有涉及CLH等待队列。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by qiuyunjie .
*/
public class Test {
public static void main (String[] args){
//新建lock
MyLock lock = new MyLock();
Test1 test1 = new Test1();
//线程一
new Thread(new Runnable() {
@Override
public void run() {
test1.m1(lock);
}
}).start();
//线程二
new Thread(new Runnable() {
@Override
public void run() {
try {
//获取锁之前先休眠一秒确保线程一先获得锁
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.lock();
System.out.println("别的线程获取锁");
lock.unlock();
}
}).start();
}
}
//自定义锁类
class MyLock{
//记录当前获的锁的线程
Thread lock = null ;
//记录重入次数
int state = 0 ;
//锁标志
boolean isLocked = false ;
//这里应该用CAS 偷懒就用synchronized
public synchronized void lock(){
Thread currentThread = Thread.currentThread() ;
//不是第一个进来,并且不是当前线程就等待
while(isLocked && lock != currentThread){
try {
//等待
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//是当前线程或者 第一次进来的线程就获取到锁
isLocked = true ;
lock = currentThread ;
//获取到几次就加几次
state ++ ;
}
public synchronized void unlock(){
//不是当前线程就不能释放锁
if(lock == Thread.currentThread()){
state -- ;
if(state == 0){
notify();
isLocked = false ;
}
}
}
}
//测试类
class Test1{
public void m1(MyLock lock){
lock.lock();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第一次进来");
m2(lock);
lock.unlock();
}
public void m2(MyLock lock){
lock.lock();
System.out.println("第二次进来");
lock.unlock();
}
}