天天看點

利用CountDownLatch實作的一個簡單的線程同步場景

package countdownlatchTest;

import java.util.concurrent.CountDownLatch;

class Worker {    
    private String name;        // 名字    
    private long workDuration;  // 工作持續時間      
    public Worker(String name, long workDuration) {        
        this.name = name;        
        this.workDuration = workDuration;    
        System.out.println("Worker: " + name + " is assigned with work time: " + workDuration);
    }      
    
    public void doWork() {        
        System.out.println(name + " begins to work...");        
        try {            
            Thread.sleep(workDuration); // 用休眠模拟工作執行的時間        
        } catch(InterruptedException ex) {
            ex.printStackTrace();        
        }
        System.out.println(name + " has finished the job...");    
    } 
}

class WorkerTestThread implements Runnable {    
    private Worker worker;    
    private CountDownLatch cdLatch;      
    public WorkerTestThread(Worker worker, CountDownLatch cdLatch) {        
        this.worker = worker;        
        this.cdLatch = cdLatch;    
    }      
    
    @Override    
    public void run() {        
        worker.doWork();        // 讓勞工開始工作        
        cdLatch.countDown();    // 工作完成後倒計時次數減1    
    } 
    
}

public class CountDownLatchTest {
    private static final int MAX_WORK_DURATION = 5000;  // 最大工作時間    
    private static final int MIN_WORK_DURATION = 1000;  // 最小工作時間      
    // 産生随機的工作時間    
    private static long getRandomWorkDuration(long min, long max) {        
        return (long) (Math.random() * (max - min) + min);    
    }      
    
    public static void main(String[] args) {    
        /* 2是次數,不是時間數
         * 将這個CountDownLatch引用賦給工作線程,每次工作線程完成任務後,調用
         * CountDownLatch.countDown, 将計數器減一。如果技術器減到0,阻塞的await方法
         * 才會傳回,重新獲得控制權
         */
        CountDownLatch latch = new CountDownLatch(2);  // should be exactly 2
        Worker w1 = new Worker("Jerry Worker 1", getRandomWorkDuration(MIN_WORK_DURATION, MAX_WORK_DURATION));  
        Worker w2 = new Worker("Jerry Worker 2", getRandomWorkDuration(MIN_WORK_DURATION, MAX_WORK_DURATION));  
        new Thread(new WorkerTestThread(w1, latch)).start();        
        new Thread(new WorkerTestThread(w2, latch)).start();          
        // latch.countDown();
        try {          
            // 僅當CountDownLatch的count降低到0時,這個阻塞的方法才會傳回
            latch.await(); 
            System.out.println("All jobs have been finished!");        
        } 
        catch (InterruptedException e) {            
            e.printStackTrace();
        }
    }
}
      

繼續閱讀