可重入的锁
“可重入锁”的概念是:自己可以再次获得自己的内部锁。比如有一条线程获得了某个对象的锁,此时这个对象还没有释放,当其再次想获得这个对象的锁的时候还是可以获得的,如果不可锁重入的话,就会造成死锁。
以上一个自选锁为例,其并不是一个可重入的锁,当使用这个锁时,如果线程进入一个加锁的方法A,再去调用另一个加锁的方法B,此时是进入不了方法B的。此处进行改造,升级为可重入的自旋锁。
package lock.reentrantLock;
import lock.ThreadLock;
import java.util.concurrent.atomic.AtomicReference;
/**
* Created by zongx on 2019/10/9.
* 可重入的自旋锁,在自旋锁的基础上,增加计数器,当前类无需再去获取锁,只是将计数器加一。释放锁的时候也只是将计数器减一,
* 当计数器减为0才会释放真正的自旋锁。
*/
public class ReentrantSpinLock implements ThreadLock{
private AtomicReference<Thread> cas = new AtomicReference<>();
private int count = 0;
@Override
public void lock() {
Thread currentThread = Thread.currentThread();
if (currentThread == cas.get()) {//当前线程与锁中线程保持一致,直接运行后续代码,锁计次加一
count++;
return;
}
while (!cas.compareAndSet(null,currentThread)) {
}
}
@Override
public void unlock() {
Thread currentThread = Thread.currentThread();
if(currentThread == cas.get()) {
if(count > 0 ) {
count--;
} else {
cas.compareAndSet(currentThread,null);
}
}
}
}
测试:
package lock.reentrantLock;
import lock.ThreadLock;
import lock.spinlock.SpinLock;
import java.util.Random;
/**
* Created by zongx on 2019/9/20.
*/
public class MyThread extends Thread {
private ThreadLock lock;
public MyThread(String name , ThreadLock lock) {
super(name);
this.lock = lock;
}
public void test1(){
lock.lock();
System.out.println("线程name:"+ super.getName() + "调用了test1方法" );
test2();
lock.unlock();
}
public void test2(){
lock.lock();
System.out.println("线程name:"+ super.getName() + "调用了test2方法" );
lock.unlock();
}
@Override
public void run() {
lock.lock();
test1();
lock.unlock();
}
}
package lock.reentrantLock;
import lock.ThreadLock;
import lock.spinlock.SpinLock;
/**
* Created by zongx on 2019/10/8.
*/
public class Demo {
public static void main(String[] args) {
ThreadLock lock = new ReentrantSpinLock();
MyThread thread1 = new MyThread("Thread1", lock);
MyThread thread2 = new MyThread("Thread2", lock);
MyThread thread3 = new MyThread("Thread3", lock);
thread1.start();
thread2.start();
thread3.start();
}
}
运行结果:
指的指出ReetrantLock与Synchronized都是可重入锁