マルチスレッド-ReentrantLockの機能と使用法

ReentrantLock は Lock インターフェイスを実装し、Lock クラスのメソッドを書き換えます。次の特性があります

1. リエントラント。つまり、同じロック オブジェクトを同じスレッド内で繰り返しロックできます。

public class TestReentrant {
    static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        method1();
    }

    public static void method1() {
        lock.lock();
        try {
            log.debug("execute method1");
            method2();
        } finally {
            lock.unlock();
        }
    }

    public static void method2() {
        lock.lock();
        try {
            log.debug("execute method2");
            method3();
        } finally {
            lock.unlock();
        }
    }

    public static void method3() {
        lock.lock();
        try {
            log.debug("execute method3");
        } finally {
            lock.unlock();
        }
    }
}

2. 中断可能。lock.lockInterruptibly() メソッドを使用します。

3. ロックのタイムアウト。lock.tryLock() メソッドを使用します。

public class TestTimeout {
    public static void main(String[] args) {
        test1();
    }

    private static void test1() {
        ReentrantLock lock = new ReentrantLock();
        Thread t1 = new Thread(() -> {
            log.debug("启动...");
            try {
                if (!lock.tryLock(1, TimeUnit.SECONDS)) {
                    log.debug("获取等待 1s 后失败,返回");
                    return;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                log.debug("获得了锁");
            } finally {
                lock.unlock();
            }
        }, "t1");

        lock.lock();
        log.debug("获得了锁");
        t1.start();
        try {
            sleep(2);
        } finally {
            lock.unlock();
        }
    }

}

4. 公平・不公平を設定可能。直接コンストラクターは ReentrantLock(boolean Fair) を渡します。

5. 複数の条件を設定できます。await、signal を使用して通信します。

public class ReentreantLock01 {
    private static Lock lock = new ReentrantLock();
    static Condition condition1 = lock.newCondition();
    static Condition condition2 = lock.newCondition();
    private static boolean flag1 = false;
    private static boolean flag2 = false;

    public static void main(String[] args) {
        new Thread(()->{
            try {
                lock.lock();
                log.info("开始干活");
                while (!flag1){
                    try {
                        log.info("进入休息1");
                        condition1.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (!flag1){
                    log.info("暂时干不了活");
                }else {
                    log.info("可以干活");
                }
            }finally {
                lock.unlock();
            }

        },"t1").start();

        new Thread(()->{
            try {
                lock.lock();
                log.info("开始干活2");
                while (!flag2){
                    try {
                        log.info("进入休息2");
                        condition2.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (!flag2){
                    log.info("暂时干不了活2");
                }else {
                    log.info("可以干活2");
                }
            }finally {
                lock.unlock();
            }
        },"t2").start();


        SleepUtils.sleep(5);
        try {
            if (lock.tryLock()) {
                log.info("主线程获取锁成功");
                flag1 = true;
                condition1.signal();
                SleepUtils.sleep(5);
                flag2 = true;
                condition2.signal();
            }
        }finally {
            lock.unlock();
        }

    }

おすすめ

転載: blog.csdn.net/weixin_42740540/article/details/124693625