package com.packtpub.java7.concurrency.chapter3.recipe3.core;import com.packtpub.java7.concurrency.chapter3.recipe3.task.Participant;import com.packtpub.java7.concurrency.chapter3.recipe3.task.Videoconference;/** * Main class of the example. Create, initialize and execute all the objects * necessaries for the example * */public class Main { /** * Main method of the example * @param args */ public static void main(String[] args) { // Creates a VideoConference with 10 participants. Videoconference conference=new Videoconference(10); // Creates a thread to run the VideoConference and start it. Thread threadConference=new Thread(conference); threadConference.start(); // Creates ten participants, a thread for each one and starts them for (int i=0; i<10; i++){ Participant p=new Participant(conference, "Participant "+i); Thread t=new Thread(p); t.start(); } }}
package com.packtpub.java7.concurrency.chapter3.recipe3.task;import java.util.concurrent.CountDownLatch;/** * This class implements the controller of the Videoconference * * It uses a CountDownLatch to control the arrival of all the * participants in the conference. * */public class Videoconference implements Runnable{ /** * This class uses a CountDownLatch to control the arrivel of all * the participants */ private final CountDownLatch controller; /** * Constructor of the class. Initializes the CountDownLatch * @param number The number of participants in the videoconference */ public Videoconference(int number) { controller=new CountDownLatch(number); } /** * This method is called by every participant when he incorporates to the VideoConference * @param participant */ public void arrive(String name){ System.out.printf("%s has arrived.\n",name); // This method uses the countDown method to decrement the internal counter of the // CountDownLatch controller.countDown(); System.out.printf("VideoConference: Waiting for %d participants.\n",controller.getCount()); } /** * This is the main method of the Controller of the VideoConference. It waits for all * the participants and the, starts the conference */ @Override public void run() { System.out.printf("VideoConference: Initialization: %d participants.\n",controller.getCount()); try { // Wait for all the participants controller.await(); // Starts the conference System.out.printf("VideoConference: All the participants have come\n"); System.out.printf("VideoConference: Let's start...\n"); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.packtpub.java7.concurrency.chapter3.recipe3.task;import java.util.concurrent.TimeUnit;/** * This class implements a participant in the VideoConference * */public class Participant implements Runnable { /** * VideoConference in which this participant will take part off */ private Videoconference conference; /** * Name of the participant. For log purposes only */ private String name; /** * Constructor of the class. Initialize its attributes * @param conference VideoConference in which is going to take part off * @param name Name of the participant */ public Participant(Videoconference conference, String name) { this.conference=conference; this.name=name; } /** * Core method of the participant. Waits a random time and joins the VideoConference */ @Override public void run() { Long duration=(long)(Math.random()*10); try { TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } conference.arrive(name); }}
JAVA并发API提供了CountDownLatch类,他是一个同步辅助类。在完成一组正在执行中的线程之前,他允许线程一直等待。这个类使用一个整数进行初始化,这个整数就是线程要等待完成的操作数目。当一个线程要等待某些操作先执行时,需要调用await()方法,这个方法让线程进入休眠直到等待的所有操作完成。当某一个操作完成后,他将调用countDown()方法将CountDownLatch类的内部计数器减1.当计数器变成0时,CountDownLatch类将唤醒所有await()方法而进入休眠的线程。