栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JUC高并发编程(09) -- 多线程锁 -- 可重入锁

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JUC高并发编程(09) -- 多线程锁 -- 可重入锁

JUC高并发编程 六、多线程锁 6.3)可重入锁

核心问题场景:当一个线程获得当前实例的锁lock,并且进入了方法A,该线程在方法A没有释放该锁的时候,是否可以再次进入使用该锁的方法B?

不可重入锁:在方法A释放锁之前,不可以再次进入方法B

可重入锁:在方法A释放该锁之前,可以再次进入方法B

不可重入锁:

当线程在访问A方法的时候,获取的A方法的锁,在A方法锁释放之前不能够访问其他方法(如方法B)的锁。

不可重入锁模型:{}{}{}{}{}都是独立的访问每一个方法,加锁 - 释放;加锁 - 释放。。。

可重入锁:

当线程在访问A方法的时候,获取A方法的锁,然后访问B方法获取B方法的锁,并计数加1,以此类推可以访问完了以后依次解锁。

可重入锁模型:{{{{}}}} 每次都可访问另一个方法,且加锁计数器加1,完全释放锁为计数器等于0

可重入锁,是指同一个线程可以重入上锁的代码段,不同的线程进入则需要进行阻塞等待。

Java的可重入锁有:reentrantLock(显式的可重入锁)【手动上锁解锁】、synchronized(隐式的可重入锁)【自动上锁解锁】

可重入锁诞生的目的:防止死锁,导致同一个线程不可重入上锁代码段,目的就是让同一个线程可以重新进入上锁代码段

6.3.1)synchronized实现可重入锁

synchronized实现可重入锁代码示例:

//synchronized实现可重入锁代码示例
public class SyncLockDemo {
    public static void main(String[] args) {
        // synchronized实现可重入锁
        Object o = new Object();
        new Thread(() -> {
            synchronized (o) {
                System.out.println(Thread.currentThread().getName() + " 外层");
​
                synchronized (o) {
                    System.out.println(Thread.currentThread().getName() + " 中层");
​
                    synchronized (o) {
                        System.out.println(Thread.currentThread().getName() + " 内层");
                    }
                }
            }
        }, "t1").start();
    }
}

输出:在外层的锁释放前,仍然可以进入上锁的中层和内层代码块

t1 外层

t1 中层

t1 内层

可重入锁又称递归锁,递归锁代码示例:

public class SyncLockDemo1 {
    public synchronized void add() {
        add();
    }
​
    public static void main(String[] args) {
        new SyncLockDemo1().add();
    }
}

输出:

Exception in thread "main" java.lang.StackOverflowError

at com.study.sync.SyncLockDemo1.add(SyncLockDemo1.java:12)

6.3.2)Lock 实现可重入锁

Lock实现可重入锁代码示例:

// Lock实现可重入锁代码示例
public class SyncLockDemo2 {
    public static void main(String[] args) {
        //Lock演示可重入锁
        Lock lock = new ReentrantLock();
        //创建线程
        new Thread(() -> {
            try {
                //上锁
                lock.lock();
                System.out.println(Thread.currentThread().getName() + " 外层");
​
                try {
                    //上锁
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + " 内层");
                } finally {
                    //释放锁
                    lock.unlock();
                }
            } finally {
                //释放做
                lock.unlock();
            }
        }, "t1").start();
​
        //创建新线程
        new Thread(() -> {
            lock.lock();
            System.out.println("aaaa");
            lock.unlock();
        }, "aa").start();
    }
}

输出:lock 需要手动上锁和解锁,如果不解锁,将会一直卡在该线程中,无法继续执行后面的线程创建操作

t1 外层

t1 内层

aaaa

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/880175.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号