1 可重入锁 (ReentrantLock和synchronized)
可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁,这样的锁就叫做可重入锁
如ReentrantLock和synchronized都是可重入锁的
如:
public class ReentrantTest1 implements Runnable {
public synchronized void get() {
System.out.println(Thread.currentThread().getName());
set();
}
public synchronized void set() {
System.out.println(Thread.currentThread().getName());
}
public void run() {
get();
}
public static void main(String[] args) {
ReentrantTest1 rt = new ReentrantTest1();
for(;;){
new Thread(rt).start();
}
}
}
输出结果,没有死锁
Thread-8492
Thread-8492
Thread-8494
Thread-8494
Thread-8495
Thread-8495
Thread-8493
Thread-8493
2 不可重入锁
简单说就是不可重入锁,与可重入锁相反,不可递归调用,否则递归调用就发生死锁
import java.util.concurrent.atomic.AtomicReference;
public class UnreentrantLock {
private AtomicReference<Thread> owner = new AtomicReference<Thread>();
public void lock() {
Thread current = Thread.currentThread();
//这句是很经典的“自旋”语法,AtomicInteger中也有
for (;;) {
if (!owner.compareAndSet(null, current)) {
return;
}
}
}
public void unlock() {
Thread current = Thread.currentThread();
owner.compareAndSet(current, null);
}
}
上面代码,如果第一次lock了,在第一次unlock前,又进行第二次lock,则发生死循环,即死锁
改造一下就变成可重入锁了
import java.util.concurrent.atomic.AtomicReference;
public class UnreentrantLock {
private AtomicReference<Thread> owner = new AtomicReference<Thread>();
private int state = 0;
public void lock() {
Thread current = Thread.currentThread();
if (current == owner.get()) {
state++;
return;
}
//这句是很经典的“自旋”式语法,AtomicInteger中也有
for (;;) {
if (!owner.compareAndSet(null, current)) {
return;
}
}
}
public void unlock() {
Thread current = Thread.currentThread();
if (current == owner.get()) {
if (state != 0) {
state--;
} else {
owner.compareAndSet(current, null);
}
}
}
}
网友评论