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

JUC并发编程八 并发架构--ReentrantLock,第1张

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

相比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();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5659775.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-16
下一篇2022-12-16

发表评论

登录后才能评论

评论列表(0条)

    保存