美文网首页
可重入锁和非可重入锁

可重入锁和非可重入锁

作者: 舒尔诚 | 来源:发表于2022-02-18 17:56 被阅读0次

    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);
                }
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:可重入锁和非可重入锁

          本文链接:https://www.haomeiwen.com/subject/ifmylrtx.html