
// ConcurrentHelloWorld.java
// Michele Loreti and the jSpace Developers, 2017 
// Modified by Andrew Davison, ad@coe.psu.ac.th, May 2023

/* This version of HelloWorld uses 
   three threads ("T1", "T2", "T3"). The first two
   add ("GREETING", "Hello") and ("NAME", "World") as 
   two separate tuples, 
   while the third thread waits for them, and prints the
   second argument of each one

  Usage:
    > compile.bat ConcurrentHelloWorld.java
    > run.bat ConcurrentHelloWorld

  Other versions: 
    * HelloWorld.java
    * RemoteHelloWorld.java
*/


import java.io.*;

import org.jspace.*;


public class ConcurrentHelloWorld
{

  public static void main(String[] argv) 
  {
    // choose one of these spaces
    Space space = new VisSpace();
    // Space space = new SequentialSpace();

    // two threads to put data into the space
    Thread t1 = new Thread(() -> {
      try {
        space.put("GREETING", "Hello"); 
      }
      catch (InterruptedException e) 
      {  System.out.println("T1 Error: " + e); }
    },"T1");  // VisSpace requires that threads be named


    Thread t2 = new Thread(() -> {
      try {
        space.put("NAME", "World");
      }
      catch (InterruptedException e) 
      {  System.out.println("T2 Error: " + e); }
    }, "T2");


    // one thread waits for two pieces of data in the space;
    /* The "GREETING" and "NAME" IDs match those used by
       the writing threads */
    Thread t3 = new Thread(() -> {
      try {
        Object[] greetingData =
             space.get( new ActualField("GREETING"), 
                        new FormalField(String.class));
        Object[] nameData =
            space.get( new ActualField("NAME"), 
                       new FormalField(String.class));

        // print both retrieved strings
        System.out.println(greetingData[1] + " " + nameData[1]);
      }
      catch (InterruptedException e) 
      {  System.out.println("T3 Error: " + e); }
    }, "T3");

    t1.start();
    t2.start();
    t3.start();

    SpaceUtils.waitTerminated(t1, t2, t3);
        /* useful for detecting when all the 
           threads have finished, and for stopping main()
           from terminating before the threads
        */
  } /* main */


}  // end of ConcurrentHelloWorld class
