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

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

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

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();
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/657700.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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