java中的锁——可重入锁 / 不可重入锁
程序员文章站
2024-01-08 09:22:23
...
一、可重入锁
可重入锁是指:可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class)。
优点:避免死锁
synchronizedvoidsetA()throwsException{
Thread.sleep(1000);
setB();
}
synchronizedvoidsetB()throwsException{
Thread.sleep(1000);
}
此代码就是一个可重入锁的一个特点。
如果不是可重入锁的话,setB可能不会被当前线程执行,可能造成死锁。
public class Test implements Runnable{
public synchronized void get(){
System.out.println(Thread.currentThread().getId());
set();
}
public synchronized void set(){
System.out.println(Thread.currentThread().getId());
}
@Override
public void run() {
get();
}
public static void main(String[] args) {
Test ss=new Test();
new Thread(ss).start();
new Thread(ss).start();
new Thread(ss).start();
}
}
public class Test implements Runnable {
ReentrantLock lock = new ReentrantLock();
public void get() {
lock.lock();
System.out.println(Thread.currentThread().getId());
set();
lock.unlock();
}
public void set() {
lock.lock();
System.out.println(Thread.currentThread().getId());
lock.unlock();
}
@Override
public void run() {
get();
}
public static void main(String[] args) {
Test ss = new Test();
new Thread(ss).start();
new Thread(ss).start();
new Thread(ss).start();
}
}
同一个线程id被连续输出两次。
结果如下:
Threadid: 8
Threadid: 8
Threadid: 10
Threadid: 10
Threadid: 9
Threadid: 9
二、不可重入锁
不可重入锁是指:与重入锁相反,不可递归调用,递归调用就发生死锁。
importjava.util.concurrent.atomic.AtomicReference;
publicclassUnreentrantLock{
privateAtomicReference owner =newAtomicReference();
publicvoidlock(){
Thread current = Thread.currentThread();
//这句是很经典的“自旋”语法,AtomicInteger中也有
for(;;) {
if(!owner.compareAndSet(null, current)) {
return;
}
}
}
publicvoidunlock(){
Thread current = Thread.currentThread();
owner.compareAndSet(current,null);
}
}