本文內容部分引自《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狀態。