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状态。

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