1. 程式人生 > 其它 >【Lock】加鎖解鎖

【Lock】加鎖解鎖

@Slf4j
public class TestLock {
    public static void main(String[] args) throws Exception{

        ReentrantLock lock = new ReentrantLock(false);
        String mainThreadName = Thread.currentThread().getName();

        System.out.println("=====BEGIN=====");
        try {
            new Thread(() -> {
                String name 
= Thread.currentThread().getName(); lock.lock(); // 第一次加鎖 System.out.println("1-1、"+lock.tryLock()); // 第二次加鎖 System.out.println("1-2、"+lock.tryLock()); // 第三次加鎖 Thread.currentThread().setName("執行緒A"); // 未解鎖前,剩餘鎖數量:3 lock.unlock(); //
解鎖,剩餘鎖數量:2 lock.unlock(); // 解鎖,剩餘鎖數量:1 lock.unlock(); // 解鎖,剩餘鎖數量:0 System.out.println(name + " lock.getHoldCount: " + lock.getHoldCount()); // 列印:0 }).start(); new Thread(() -> { String name = Thread.currentThread().getName();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2、"+lock.tryLock()); Thread.currentThread().setName("執行緒B"); //System.out.println(name); if (lock.isLocked()) { System.out.println(name + " =1= lock.getHoldCount: " + lock.getHoldCount()); System.out.println(name+"解鎖"); lock.unlock(); System.out.println(name + " =2= lock.getHoldCount: " + lock.getHoldCount()); } }).start(); new Thread(() -> { String name = Thread.currentThread().getName(); try { Thread.sleep(200); // 睡眠時間與執行緒B相同,下面lock.unlock()會報IllegalMonitorStateException // Thread.sleep(400); // lock.unlock()不會報IllegalMonitorStateException } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("3、"+lock.tryLock()); Thread.currentThread().setName("執行緒C"); if (lock.isLocked()) { // 因為睡眠時間相同,所以可能出現的情況:執行緒B獲取到鎖但還未解鎖,再結合lock.isLocked()原始碼(any thread), // 即鎖還未被釋放,進入判斷後lock.unlock()失敗,因為不符合:If the current thread is the holder of this lock System.out.println(name+"解鎖"); lock.unlock(); } }).start(); } catch (Exception e) { log.error(e.getMessage(),e); } System.out.println(mainThreadName+" lock.isLocked: " + lock.isLocked()); System.out.println("=====END====="); } }