lock和try-finally语句块的正确写法

  1. lock()方法必须写在try语句块之外;
  2. lock()方法和try语句块之间,不能有其他代码,避免其他代码遇到异常,导致unlock()方法得不到执行,锁无法释放;
  3. unlock()方法必须写在finally语句块的第1行,避免其他代码遇到异常,导致unlock()方法得不到执行,锁无法释放;
package com.yang.service;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @description: lock和try-finally语句块的正确写法:
 * <p>
 * 1.lock()方法必须写在try语句块之外;
 * 2.lock()方法和try语句块之间,不能有其他代码,避免其他代码遇到异常,导致unlock()方法得不到执行,锁无法释放;
 * 3.unlock()方法必须写在finally语句块的第1行,避免其他代码遇到异常,导致unlock()方法得不到执行,锁无法释放;
 * 
 * @author: Yang JianXiong
 * @since: 2023/5/13
 */
public class LockAndTry {

    /**
     * 锁对象
     */
    private static final ReentrantLock lock = new ReentrantLock();

    /**
     * 正确的写法:
     * 首先,lock()写在try语句块之外。
     * 其次,lock()和try语句块之间没有其他语句。
     * 再者,unlock()必须写在finally语句块的第1行。
     */
    private static void good() {
        int prepare = 1 / 0;
        lock.lock();
        try {
            int processBiz = 1 / 0;
        } finally {
            lock.unlock();
            int releaseResource = 1 / 0;
        }
    }

    /**
     * 错误一:lock()写在try语句块内部,且不为try的第1行:
     * 由于int processBiz = 1 / 0抛出异常,lock.lock()得不到执行,
     * 但是finally块内的unlock()必然会执行,
     * 由于当前线程还未获得该锁,故unlock()会抛出异常
     * 此异常会覆盖掉int processBiz = 1 / 0语句的异常信息
     * 导致真正的异常信息丢失
     */
    private static void bad1() {
        int prepare = 1 / 1;
        try {
            int processBiz = 1 / 0;
            lock.lock();
        } finally {
            lock.unlock();
            int releaseResource = 1 / 0;
        }
    }

    /**
     * 错误二:lock()写在try语句块内部,且是try的第1行:
     * lock()语句在获取锁时,可能抛出异常
     * 但是finally块内的unlock()必然会执行,
     * 由于当前线程还未获得该锁,故unlock()会抛出异常
     */
    private static void bad2() {
        int prepare = 1 / 1;
        try {
            lock.lock();  // 可能抛异常
            int processBiz = 1 / 0;
        } finally {
            lock.unlock();
            int releaseResource = 1 / 0;
        }
    }

    /**
     * 错误三:lock()写在try语句块之外,但之间有int prepare = 1 / 0语句
     * int prepare = 1 / 0抛出异常,后续代码将不会执行,
     * 锁将得不到释放
     */
    private static void bad3() {
        lock.lock();
        int prepare = 1 / 0;
        try {
            int processBiz = 1 / 0;
        } finally {
            lock.unlock();
            int releaseResource = 1 / 0;
        }
    }

    /**
     * 错误四:finally语句块内的lock()不是第1行
     * 若int releaseResource = 1 / 0语句抛出异常
     * 锁将得不到释放
     */
    private static void bad4() {
        int prepare = 1 / 1;
        lock.lock();
        try {
            int processBiz = 1 / 0;
        } finally {
            int releaseResource = 1 / 0;
            lock.unlock();
        }
    }

}

posted @ 2023-05-13 11:24  JaxYoun  阅读(385)  评论(0编辑  收藏  举报