Java多線程問題--方法getHoldCount()、getQueueLength()和getWaitQueueLength()的用法和區別

本文內容部分引自《Java多線程編程核心技術》,感謝作者!!!

代碼地址:https://github.com/xianzhixianzhixian/thread.git

方法getHoldCount()、getQueueLength()和getWaitQueueLength()用法和區別

1、lock.getHoldCount()作用是查詢當前線程保持鎖定的個數,也就是調用lock()方法的次數,注意這裏“保持鎖定“”的意思是,當前正在持有鎖的線程的個數。

2、lock.getQueueLength()的作用是返回正在等待獲取此鎖定的線程的估計數。比如有5個線程,1個線程首先執行await()方法,那麼在調用getQueueLength()方法後返回值是4,說明有4個線程同時在等待lock的釋放。注意這裏“等待獲取此鎖”的意思是當前處於lock狀態且未持有鎖的線程的個數。

3、lock.getWaitQueueLength(Condition condition)方法的作用是返回等待與此鎖定相關的給定條件Condition的線程估計數。比如說有5個線程,每個線程都執行了同一個condition對象的await()方法,則調用getWaitQueueLength(Condition condition)方法的返回值是5。特別注意:這裏返回值統計的是調用同一個condtion的await()方法且處於await狀態的線程個數。

代碼示例

ServiceGetHoldCount.java

/**
 * getHoldCount()的使用示例
 * lock.getHoldCount()作用是查詢當前線程保持鎖定的個數,也就是調用lock()方法的次數
 *
 * 注意這裏保持鎖定的意思是,當前正在持有鎖的線程的個數
 * @author: xianzhixianzhixian
 * @date: 2019-01-15 21:15
 */
public class ServiceGetHoldCount {
    public ReentrantLock lock = new ReentrantLock();
    public void serviceGetHoldCount1(){
        try {
            lock.lock();
            System.out.println("serviceGetHoldCount1 getHoldCount()="
                    +lock.getHoldCount());
            serviceGetHoldCount2();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void serviceGetHoldCount2(){
        try {
            lock.lock();
            System.out.println("serviceGetHoldCount2 getHoldCount()="
                    +lock.getHoldCount());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

ServiceGetQueueLength.java

/**
 * getQueueLength()的使用示例
 * lock.getQueueLength()的作用是返回正在等待獲取此鎖定的線程的估計數
 * 比如有5個線程,1個線程首先執行await()方法,那麼在調用getQueueLength()方法後返回值是4,說明有4個線程同時在等待lock的釋放
 *
 * 注意這裏等待獲取此鎖的意思是當前處於lock狀態且未持有鎖的線程的個數
 * @author: xianzhixianzhixian
 * @date: 2019-01-15 21:24
 */
public class ServiceGetQueueLength {
    public ReentrantLock lock = new ReentrantLock();
    public void serviceGetQueueLength(){
        try {
            lock.lock();
            System.out.println("ThreadName="+Thread.currentThread().getName()
                        +"進入方法");
            Thread.sleep(Integer.MAX_VALUE);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

ServiceGetWaitQueueLength.java

/**
 * getWaitQueueLength(Condition condition)的使用示例
 * lock.getWaitQueueLength(Condition condition)方法的作用是返回等待與此鎖定相關的給定條件Condition的線程估計數
 * 比如說有5個線程,每個線程都執行了同一個condition對象的await()方法,則調用getWaitQueueLength(Condition condition)
 * 方法的返回值是5
 *
 * 特別注意:這裏返回值統計的是調用同一個condtion的await()方法且處於await狀態的線程個數
 * @author: xianzhixianzhixian
 * @date: 2019-01-15 21:34
 */
public class ServiceGetWaitQueueLength {
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    public void awaitMethod(){
        try {
            lock.lock();
            condition.await();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void notifyMethod(){
        try {
            lock.lock();
            System.out.println("有"+lock.getWaitQueueLength(condition)
                        +"個線程正在等待condition");
            condition.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

Run.java

/**
 * getHoldCount()、getQueueLength()和getWaitQueueLength()區別
 * @author: xianzhixianzhixian
 * @date: 2019-01-15 21:20
 */
public class Run {
    public static void main(String[] args) throws Exception {
        ServiceGetHoldCount serviceGetHoldCount = new ServiceGetHoldCount();
        serviceGetHoldCount.serviceGetHoldCount1();
        System.out.println("serviceGetHoldCount.lock.getQueueLength()"+serviceGetHoldCount.lock.getQueueLength());



        final ServiceGetQueueLength serviceGetQueueLength = new ServiceGetQueueLength();
        Runnable runnableGetQueueLength = new Runnable() {
            @Override
            public void run() {
                serviceGetQueueLength.serviceGetQueueLength();
            }
        };
        Thread[] threadArrayGetQueueLength = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threadArrayGetQueueLength[i] = new Thread(runnableGetQueueLength);
        }
        for (int i = 0; i < 10; i++) {
            threadArrayGetQueueLength[i].start();
        }
        Thread.sleep(2000);
        System.out.println("有線程數:"+ serviceGetQueueLength.lock.getQueueLength()+"在等待獲取鎖!");



        final ServiceGetWaitQueueLength serviceGetWaitQueueLength = new ServiceGetWaitQueueLength();
        Runnable runnableGetWaitQueueLength = new Runnable() {
            @Override
            public void run() {
                serviceGetWaitQueueLength.awaitMethod();
            }
        };
        Thread[] threadArrayGetWaitQueueLength = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threadArrayGetWaitQueueLength[i] = new Thread(runnableGetWaitQueueLength);
        }
        for (int i = 0; i < 10; i++) {
            threadArrayGetWaitQueueLength[i].start();
            //serviceGetWaitQueueLength.notifyMethod();
        }
        Thread.sleep(2000);
        serviceGetWaitQueueLength.notifyMethod(); //只喚醒一個處於await狀態的線程
    }
}

運行結果:getHoldCount()的返回值爲2,因爲有兩個線程獲得了鎖;getQueueLength()的返回值爲9,因爲此時有一個線程獲得了鎖並且一直處於sleep狀態,而其它九個線程處於等待鎖被釋放的狀態;getWaitQueueLength(Condition condition)的返回值爲10,因爲所有10個線程都調用了condition.await()方法且都處於await狀態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章