Java多執行緒——獲取多個執行緒任務執行完的時間
問題
最近我在處理一批資料,用多執行緒來處理,我想知道大概多久能處理完。比如我先用多執行緒處理 100 條資料,統計下用時,然後根據總的資料量就可以大概估算出處理完這批資料要多久。
使用 CountDownLatch 計時
思路:用兩個 CountDownLatch 倒數計時鎖:開始計時鎖,任務結束計時鎖。開始計時鎖在子執行緒任務開始時通過 await() 阻塞所有子執行緒,然後在主執行緒中通過 CountDownLatch 控制所有子執行緒同時開始獲取開始時間;任務結束計時鎖 CountDownLatch 在每個子執行緒執行完後都 countDown 一次,直到所有子執行緒執行完,主執行緒開始記錄所有任務執行結束時間。
示例程式碼
/**
* ClassName: ThreadTiming <br/>
* Function: 計算多個執行緒任務執行完後的用時<br/>
*
* @author gary.liu
* @date 2017/6/24
*/
public class ThreadTiming {
private int nThread;
private CountDownLatch startGate;
private CountDownLatch endGate;
public ThreadTiming(int nThread, CountDownLatch startGate, CountDownLatch endGate) {
this.nThread = nThread;
this.startGate = startGate;
this.endGate = endGate;
}
class worker implements Runnable {
public void run() {
try {
startGate.await();
Random random = new Random();
int num = random.nextInt(500) + 500;
System.out.println(Thread.currentThread().getName() + " start and sleep: " + num + "ms");
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
endGate.countDown();
}
}
}
public long timeTasks() {
for(int i = 0; i < nThread; i++){
Thread thread = new Thread(new worker());
thread.start();
}
long start = System.currentTimeMillis();
//所有阻塞的任務同時開始
startGate.countDown();
try {
//主執行緒阻塞,等待其他所有 worker 執行緒完成後再執行
endGate.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("用時: " + (end - start) + "ms");
return end - start;
}
public static void main(String[] args) {
int nThread = 5;
CountDownLatch startGate = new CountDownLatch(1);
CountDownLatch endGate = new CountDownLatch(nThread);
new ThreadTiming(nThread, startGate, endGate).timeTasks();
}
}
執行結果
Thread-4 start and sleep: 897ms
Thread-0 start and sleep: 811ms
Thread-2 start and sleep: 678ms
Thread-3 start and sleep: 582ms
Thread-1 start and sleep: 576ms
用時: 903ms
可以看到總用時比花費最長時間的執行緒任務時間多一點,隨著併發量越大,達到可同時併發執行的執行緒最大數後,用時會越久。下面執行緒池的例子,限制了併發執行緒數後,可以明顯的看到這一點。
用柵欄 CyclicBarrier 應該也是可以實現的,也可以和wait()、notifyAll() 混用來實現 ,這裡就不在具體展開了。
使用執行緒池中方法計時
執行緒池中提供了監控執行緒池執行的一些方法,這裡通過執行緒池的 isTerminated()
方法不斷檢測,執行緒池中的任務是否都執行完成了,來獲取所有任務結束時間。
示例程式碼
public class ExecuteOrderPractice {
public void orderPractice(){
ExecutorService executorService = Executors.newFixedThreadPool(3);
long start = System.currentTimeMillis();
for(int i = 0; i < 5; i++){
executorService.execute(new Runnable() {
@Override
public void run() {
try{
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " do something");
}catch (InterruptedException e){
e.printStackTrace();
}
}
});
}
executorService.shutdown();
while(true){
if(executorService.isTerminated()){
//System.out.println("Finally do something ");
long end = System.currentTimeMillis();
System.out.println("用時: " + (end - start) + "ms");
break;
}
}
}
public static void main(String[] args){
new ExecuteOrderPractice().orderPractice();
}
}
執行結果
pool-1-thread-1 do something
pool-1-thread-3 do something
pool-1-thread-2 do something
pool-1-thread-1 do something
pool-1-thread-3 do something
用時: 2010ms
參考資料
《Java 併發程式設計實戰》
相關文章
- 【java】【多執行緒】獲取和設定執行緒名字、獲取執行緒物件(3)Java執行緒物件
- Java多執行緒——執行緒Java執行緒
- Python建立多執行緒任務並獲取每個執行緒返回值Python執行緒
- Swift多執行緒:使用Thread進行多執行緒間通訊,協調子執行緒任務Swift執行緒thread
- Java多執行緒-執行緒中止Java執行緒
- Java多執行緒——執行緒池Java執行緒
- java多執行緒5:執行緒間的通訊Java執行緒
- java 多執行緒守護執行緒Java執行緒
- Java多執行緒-執行緒通訊Java執行緒
- Java多執行緒-執行緒狀態Java執行緒
- Java多執行緒(2)執行緒鎖Java執行緒
- java多執行緒9:執行緒池Java執行緒
- Java多執行緒之執行緒中止Java執行緒
- 【java多執行緒】(二)執行緒停止Java執行緒
- Java多執行緒——守護執行緒Java執行緒
- Java多執行緒16:執行緒組Java執行緒
- Java多執行緒18:執行緒池Java執行緒
- .net使用Task多執行緒執行任務 .net限制執行緒數量執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- 多執行緒和多執行緒同步執行緒
- 多執行緒【執行緒池】執行緒
- 多執行緒--執行緒管理執行緒
- 執行緒與多執行緒執行緒
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- Java多執行緒(一)多執行緒入門篇Java執行緒
- 多執行緒-獲取和設定執行緒物件名稱執行緒物件
- 【Java】【多執行緒】執行緒池簡述Java執行緒
- java多執行緒系列之執行緒池Java執行緒
- 多執行緒-執行緒控制之休眠執行緒執行緒
- 多執行緒-執行緒控制之加入執行緒執行緒
- 多執行緒-執行緒控制之禮讓執行緒執行緒
- 多執行緒-執行緒控制之中斷執行緒執行緒
- java——多執行緒Java執行緒
- java 多執行緒Java執行緒
- 【Java】多執行緒Java執行緒
- JAVA 多執行緒 ??Java執行緒
- java多執行緒Java執行緒