JUC并发编程八 并发架构--ReentrantLock

本文详细探讨了ReentrantLock相对于synchronized的优势,包括可中断、超时等待、公平锁以及支持多个条件变量。通过实例代码展示了ReentrantLock的可重入性、可中断性和锁超时功能,并解释了如何使用条件变量实现线程间的协调。
摘要由CSDN通过智能技术生成

相比synchronized,ReentrantLock具备以下特点:

  1. 可中断
  2. 可以设置超长时间
  3. 可以设置为公平锁
  4. 可以支持多个条件变量
    与synchronized一样,都支持可重入.
    在这里插入图片描述

验证可重入

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantLock;

@Slf4j(topic = "c.TestReentrantLock")
public class TestReentrantLock {
    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
            lock.lock();

            try{
                log.debug("进入主方法");
                m1();
            }finally {
                lock.unlock();
            }
    }

    // 测试可重入
    public static void m1() {
        lock.lock();
        try{
            log.debug("进入m1方法");
            m2();
        }finally {
            lock.unlock();
        }
    }

    public static void m2() {
        lock.lock();
        try{
            log.debug("进入m2方法");
        }finally {
            lock.unlock();
        }
    }
}

验证可打断性

lock()方法不具备打断性

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantLock;

@Slf4j(topic = "c.TestReentrantLock")
public class TestReentrantLock {
    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {

        // 防止无限制的等待下去

        Thread t1 = new Thread(()->{
            lock.lock();//lock()方法不能被打断
            try{
                log.debug("获取锁");
            }finally {
                lock.unlock();
                log.debug("finally...");
            }
        });


        lock.lock();
        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 去打断t1,不起作用。因为lock()方法不能被打断
        t1.interrupt();
    }
    
}

locklockInterruptibly方法可以被打断,停止线程无限制的等待.

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantLock;

@Slf4j(topic = "c.TestReentrantLock")
public class TestReentrantLock {
    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {

        // 防止无限制的等待下去

        Thread t1 = new Thread(()->{

            try{
                log.debug("尝试获取锁");
                lock.lockInterruptibly();//locklockInterruptibly方法可以被打断
            }catch (InterruptedException e){
                e.printStackTrace();
                log.debug("没有或得锁, 返回");
                return;
            }

            try{
                log.debug("获取锁");
            }finally {
                lock.unlock(); // 释放锁
                log.debug("finally...");
            }
        });


        lock.lock();
        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.debug("打断t1");
        // 去打断t1,不起作用。因为lock()方法不能被打断
        t1.interrupt();
    }
}

验证锁超时

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j(topic = "c.TestReentrantLock")
public class TestReentrantLock {
    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        Thread t = new Thread(()->{

//            if(!lock.tryLock()){
//                log.debug("获取锁失败");
//                return;
//            }

            try {
                // 尝试获取锁,如果1秒内,获取不到锁就会获取锁失败
                if(!lock.tryLock(1,TimeUnit.SECONDS)){ 
                    log.debug("获取锁失败");
                    return;
                }
            } catch (InterruptedException e) {
                // 表示可以调用 interrupt()方法,打断线程
                log.debug("获取锁失败");
                e.printStackTrace();
                return;
            }

            try{
                log.debug("获取锁成功");
            }finally {
                lock.unlock();
            }

        },"t1");


        lock.lock();
        log.debug("获取锁");
        t.start();
        try {
            Thread.sleep(2000); // 睡眠2秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.debug("释放锁");
        lock.unlock();

    }
}

验证条件变量

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j(topic = "c.TestCondition")
public class TestCondition {

    static boolean hasCigarette = false;
    static boolean hasTakeout = false;
    static ReentrantLock ROOM = new ReentrantLock();
    static Condition waitCigaretteSet = ROOM.newCondition();
    static Condition waitTakeoutSet = ROOM.newCondition();

    public static void main(String[] args) {
        new Thread(()->{
            ROOM.lock();
            try{
                log.debug("烟送到没?[{}]",hasCigarette);
                while(!hasCigarette){
                    log.debug("没烟,先歇会...");
                    try {
                        waitCigaretteSet.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                log.debug("开始干活...");
            }finally {
                ROOM.unlock();
            }
        },"小南").start();

        new Thread(()->{
            ROOM.lock();
            try{
                log.debug("外卖送到没?[{}]",hasTakeout);
                while(!hasTakeout){
                    log.debug("没外卖,先歇会...");
                    try {
                        waitTakeoutSet.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                log.debug("开始干活...");
            }finally {
                ROOM.unlock();
            }
        },"小女").start();

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

        new Thread(()->{
            ROOM.lock();
            try{
                hasCigarette = true;
                waitCigaretteSet.signal();
            }finally {
                ROOM.unlock();
            }
        }).start();

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

        new Thread(()->{
            ROOM.lock();
            try{
                hasTakeout = true;
                waitTakeoutSet.signal();
            }finally {
                ROOM.unlock();
            }
        }).start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值