001 /*
002 *
003 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
004 *
005 */
006 package demo.coordination;
007
008 import java.text.DateFormat;
009 import java.util.Date;
010 import java.util.concurrent.BrokenBarrierException;
011 import java.util.concurrent.CyclicBarrier;
012
013 /**
014 * Sample to demonstrate how to use CyclicBarrier to coordinate between JVMs
015 */
016 public class Main {
017 // banner text displayed on startup
018 private static String text0 = "\n"
019 + "JVM Coordination\n"
020 + "\n"
021 + "This sample application show how to coordinate threads in a multi-VM\n"
022 + "environment using the same patterns one would use in a multi-threaded\n"
023 + "single-VM environment.\n";
024
025 // these are the text messages we use to display the state of the application
026 private static String text1 = "Application started; I expect a total of @TOKEN@ VMs that will be participating.\n"
027 + "At this point the application is waiting for the other pariticipants (or VMs) to startup.\n"
028 + "When all of the participants are available, it will perform its task and exit.\n\n"
029 + "Notice that all the other participants also come into a wait state just like the first VM that\n"
030 + "you launched; they will only proceed as soon as the number of VMs that you have launched\n"
031 + "matches the number of participants it expects.\n\n"
032 + "Waiting for all other VMs to join...\n";
033 private static String text2 = "I am node: @TOKEN@\n"
034 + "The number of VMs that I expect to participate has launched.\n"
035 + "I will now perform my task by printing today's date and current time:\n\n"
036 + "Here it is:\n@TOKEN@\n\n"
037 + "I have completed my task."
038 + "I am now waiting for all the other VMs finish their task...\n";
039 private static String text3 = "All of the participating VMs have completed their task.\n"
040 + "I am stopping now.";
041
042 private int expectedParticipants;
043 private CyclicBarrier enterBarrier;
044 private CyclicBarrier exitBarrier;
045 private static int MINIMUM_EXPECTED_PARTICIPANTS = 2;
046
047 /**
048 * Create an instance, setting the number of VMs expected to participate in
049 * the demo.
050 */
051 public Main(int expectedParticipants) {
052 // enforce minimum number of participants
053 if (expectedParticipants < MINIMUM_EXPECTED_PARTICIPANTS) {
054 expectedParticipants = MINIMUM_EXPECTED_PARTICIPANTS;
055 System.out.println("(You did not pass an argument, I'm assuming "
056 + expectedParticipants + " VMs will be participating)\n");
057 }
058 this.expectedParticipants = expectedParticipants;
059 this.enterBarrier = new CyclicBarrier(expectedParticipants);
060 this.exitBarrier = new CyclicBarrier(expectedParticipants);
061 }
062
063 /**
064 * Start up multiple threads and wait. Once all the theads have started,
065 * execute some code. When all threads have finished executing the code,
066 * coordinate the shutdown of the participants.
067 */
068 public void run() {
069 try {
070 // wait for all participants before performing tasks
071 System.out.println(text1.replaceFirst("@TOKEN@", Integer
072 .toString(expectedParticipants)));
073 enterBarrier.await();
074
075 // perform task once all of the expected participants is present
076 String currentDateAndTime = DateFormat.getDateTimeInstance(
077 DateFormat.SHORT, DateFormat.SHORT).format(new Date());
078 System.out.println(text2.replaceFirst("@TOKEN@",
079 this + Integer.toString(expectedParticipants)).replaceFirst(
080 "@TOKEN@", currentDateAndTime));
081
082 // wait for all participants to complete their task before exiting
083 exitBarrier.await();
084 System.out.println(text3);
085 } catch (InterruptedException ie) {
086 throw new RuntimeException(ie);
087 } catch (BrokenBarrierException bbe) {
088 throw new RuntimeException(bbe);
089 }
090 }
091
092 public static final void main(String[] args) throws Exception {
093 System.out.println(text0);
094
095 int expectedParticipants = 0;
096 try {
097 expectedParticipants = Integer.parseInt(args[0]);
098 } catch (Exception e) {
099 }
100
101 (new Main(expectedParticipants)).run();
102 }
103 }
|