JavaSE-多线程(5)- Reentrant Lock (可重入锁)1

本文通过两个示例详细解释了 Java 中的 ReentrantLock 可重入锁特性。在第一个例子中,不同线程无法重入同一把锁,导致线程按顺序执行。而在第二个例子中,同一线程可以重入同一把锁,允许在持有锁的情况下调用需要同一锁的方法,展示了可重入锁的特性。这两个实例揭示了 ReentrantLock 在多线程环境中的行为和重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaSE-多线程(5)- Reentrant Lock (可重入锁1)

简单解释

线程A 在执行加锁方法 m 时获得锁 L,如果在m方法中调用的 方法 n 同时需要获得锁 L,那么不会出现互斥现象,即同一线程可重入同一锁对象

不同线程之间无法重入锁

例1
下例中,m1方法每隔1秒打印一次i值,共打印10次,m2方法直接输出一段文字,t1线程调用ReentrantLock1对象m1方法,主线程 睡眠 1秒后 t2 线程启动调用 ReentrantLock1 对象m2方法,由打印结果可知,t2线程在t1线程执行完后才开始执行,而不是在等待1秒之后执行的。原因在于m1,m2方法的调用都需要获得ReentrantLock1 对象这个锁,t2线程会等待t1线程执行完m1方法释放锁后才开始执行。由此可见,不同线程在执行期间无法获得同一把锁,即无法重入锁

package com.hs.example.base.multithread.day01;

public class ReentrantLock1 {

    public synchronized void m1() {
        System.out.println("m1 start...");
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("m1 end...");
    }

    public synchronized void m2() {
        System.out.println(Thread.currentThread().getName() + " m2 start...");
    }

    public static void main(String[] args) {
        ReentrantLock1 reentrantLock1 = new ReentrantLock1();
        Thread t1 = new Thread(reentrantLock1::m1,"t1");
        t1.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t2 = new Thread(reentrantLock1::m2,"t2");
        t2.start();
    }
}

m1 start...
t1 : 0
t1 : 1
t1 : 2
t1 : 3
t1 : 4
t1 : 5
t1 : 6
t1 : 7
t1 : 8
t1 : 9
m1 end...
t2 m2 start...
同一线程可重入锁

例2
例2是例1的改编,m1方法调用同时需要ReentrantLock2 锁对象的m2方法,由结果可知t1线程调用m1方法持有锁后,接着调用m2方法可继续持有锁对象

package com.hs.example.base.multithread.day01;

public class ReentrantLock2 {

    public synchronized void m1() {
        System.out.println("m1 start...");
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(i == 2){
                m2();
            }
        }
        System.out.println("m1 end...");
    }

    public synchronized void m2() {
        System.out.println(Thread.currentThread().getName() + " m2 start...");
    }

    public static void main(String[] args) {
        ReentrantLock2 reentrantLock1 = new ReentrantLock2();
        Thread t1 = new Thread(reentrantLock1::m1,"t1");
        t1.start();
    }
}

m1 start...
t1 : 0
t1 : 1
t1 : 2
t1 m2 start...
t1 : 3
t1 : 4
t1 : 5
t1 : 6
t1 : 7
t1 : 8
t1 : 9
m1 end...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值