ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java------多线程_高级主题_可重入锁_原理实现(十六)

2021-12-13 11:34:14  阅读:184  来源: 互联网

标签:重入 Java lock void InterruptedException throws ------ 多线程 public


Java------多线程_高级主题_可重入锁_原理实现(十六)
可重入锁:
锁作为并发共享数据保证一致性的工具,大多数内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且会将这个锁的计数值加1,而当线程推出同步代码块时,计数器会递减,当数值等于0时,锁释放,如果没有可重入的支持,在第二次企图获得锁时,将会进入死锁状态,可重入锁随处可见。
案例一:可重入锁

package cooperation;

/**
 * 可重入锁:锁可以延续使用
 */
public class ThreadLock01 {
    public void test() throws InterruptedException {
        //第一次获得锁
        synchronized (this){
            //第二次获得同样的锁
            while (true){
                synchronized (this){
                    System.out.println("可重入锁");
                }
                Thread.sleep(1000);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new ThreadLock01().test();
    }
}

案例二:模拟不可重入锁,a方法调用b方法,会一直进行等待,

package cooperation;

/**
 * 不可重入锁:锁不可以延续使用
 */
public class ThreadLock02 {
    Lock lock = new Lock();
    public void  a() throws InterruptedException {
        lock.lock();
        b();
        lock.unlock();
    }
    //此时不可重入
    public void b() throws InterruptedException {
        lock.lock();
        lock.unlock();
    }


    public static void main(String[] args) throws InterruptedException {
        new ThreadLock02().a();
    }
}
//类:不可重入锁
class Lock{
    //是否占用
    private boolean isLocked = false;
    //使用锁
    public synchronized void lock() throws InterruptedException {
        if (isLocked){
            System.out.println("正在等待");
            //等待
            wait();
        }else {
            System.out.println("表明该锁被占用");
            isLocked = true;
        }
    }
    //释放锁
    public synchronized void unlock(){
        isLocked = false;
        //唤醒
        notify();
    }
}

案例三:将案例二的不可重入锁,改写为可重入锁,需要用到计数器表明,该锁已重入次数,以及存储线程,证明锁的调用对象

package cooperation;

/**
 * 不可重入锁:锁不可以延续使用
 */
public class ThreadLock03 {
    ReLock lock = new ReLock();
    public void  a() throws InterruptedException {
        lock.lock();
        b();
        lock.unlock();
    }
    //此时不可重入
    public void b() throws InterruptedException {
        lock.lock();
        lock.unlock();
    }


    public static void main(String[] args) throws InterruptedException {
        new ThreadLock03().a();
    }
}
//改写,可重入锁
class ReLock{
    //是否占用
    private boolean isLocked = false;
    //存储线程
    Thread lockedBy = null;
    //计数器
    private int holdCount = 0;
    //使用锁
    public synchronized void lock() throws InterruptedException {
        Thread thread = Thread.currentThread();
        if (isLocked && lockedBy != thread){
            System.out.println("正在等待");
            //等待
            wait();
        }else {
            System.out.println("加锁");
            isLocked = true;
            lockedBy = thread;
            holdCount ++;
        }
    }
    //释放锁
    public synchronized void unlock(){
        Thread thread = Thread.currentThread();
        if (thread == lockedBy){
            holdCount --;
            System.out.println("释放锁,计数器为"+holdCount);
            if (holdCount ==0){
                System.out.println("完全释放锁");
                isLocked = false;
                //唤醒
                notify();
                lockedBy =null;
            }
        }

    }
}

JUC包下有个ReentrantLock,案例三就是模拟该类所写。

标签:重入,Java,lock,void,InterruptedException,throws,------,多线程,public
来源: https://blog.csdn.net/cz_chen_zhuo/article/details/121899454

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有