首页 > 其他 > 详细

可重入锁与不可重入锁

时间:2021-01-24 18:25:14      阅读:27      评论:0      收藏:0      [点我收藏+]

可重入锁(递归锁)

定义:可以递归调用的锁(当某个线程执行某个方法已经获得该锁,在方法中可以再次获取该锁,并且不会发生死锁(前提时同一个对象或Class))
可重入:某个线程已经获得了某个锁,可以再次获取锁而不会出现死锁。

注意:synchronized和ReentrantLock都时可重入锁。

不可重入锁

定义:不可以递归调用的锁(当某个线程执行某个方法已经获得该锁,在方法中再次获取该锁时,会发生阻塞)

自定义可重入锁

package juc.lock.Reentrant;

//自定义可重入锁
public class Lock {
    private boolean isLock = false;//判断当前锁状态,
    private Thread currentThread = null;//当前线程
    private int lockCount = 0;//当前锁的层数
    //加锁方法
    public synchronized void lock(){
        while (isLock && currentThread != Thread.currentThread()){//当第二次加锁时,第二个条件为false
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        isLock = true;
        currentThread = Thread.currentThread();
        lockCount++;
    }
    //解锁方法
    public synchronized void unlock(){
        if (isLock && currentThread == Thread.currentThread()){
            if (--lockCount==0){
                isLock=false;
                notify();
            }
        }
    }
}
class Test{

    Lock lock = new Lock();//自定义可重入锁

    public static void main(String[] args) {
        Test test = new Test();

        new Thread(()->{
            test.eat();
        },"A").start();

        new Thread(()->{
            test.drink();
        },"B").start();
    }
    public void eat(){
        try {
            lock.lock();
            System.out.println("线程"+Thread.currentThread().getName()+"->eat");
            Thread.sleep(1000);
            drink();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
    public void drink(){
        try {
            lock.lock();
            System.out.println("线程"+Thread.currentThread().getName()+"->drink");
        }finally {
            lock.unlock();
        }
    }
}

运行结果:
技术分享图片

自定义不可重入锁

package juc.lock.nonReentrant;

//自定义不可重入锁
public class Lock {
    private boolean isLock = false;//判断当前锁状态
    public synchronized void lock(){
        while (isLock){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            isLock = true;
        }
    }
    public synchronized void unlock(){
        if (isLock){
            isLock = false;
            notify();
        }
    }
}
class Test{
    private Lock lock = new Lock();//自定义不可重入锁

    public static void main(String[] args) {
        Test test=new Test();
        new Thread(()->{
            test.eat();
        },"A").start();

        new Thread(()->{
            test.drink();
        },"B").start();
    }
    public void eat(){
        try {
            lock.lock();
            System.out.println("线程"+Thread.currentThread().getName()+"->eat");

            Thread.sleep(1000);

            drink();
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void drink(){
        try {
            lock.lock();
            System.out.println("线程"+Thread.currentThread().getName()+"->drink");
            lock.unlock();
        } finally {
            lock.unlock();
        }
    }
}

运行结果:
技术分享图片

可重入锁与不可重入锁

原文:https://www.cnblogs.com/code-xu/p/14321214.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!