/** * A simple node implementation used in an implementation of the one-dimensional finite * difference computation described in "Designing and Building Parallel Programs" by * Ian Foster (see Section 1.4 - http://www-unix.mcs.anl.gov/dbpp/text/node10.html). * * @author Scott W. Russell * @version 5/2/2008 for CS333 Spring 2008 */ public class Node implements Runnable { /** * Constructor for objects of class Node */ public Node(String id, double value, Node left, Node right) { // initialise instance variables this.id = id; this.value = value; this.left = left; this.right = right; this.leftReceived = false; this.rightReceived = false; } /** * */ public double getValue() { return this.value; } /** * Method to change the neighbor of a node. * * @param setLeft if true set left neighbor to specified node, else set right * @param node the node to make this node's neighbor */ public void setNeighbor(boolean setLeft, Node node) { if (setLeft) { this.left = node; } else { this.right = node; } } /** * Method to send data to a neighbor. * * @param setLeft if true set left neighbor to specified node, else set right * @param value to send to neighbor */ public void sendToNeighbors() { if (this.left != null) { this.left.receiveFromNeighobor(RIGHT,value); } if (this.right != null) { this.right.receiveFromNeighobor(LEFT,value); } } /** * Method to receive neighbor's data. * * @param setLeft if true set left neighbor to specified node, else set right * @param value the value of neighbor's node */ public void receiveFromNeighobor(boolean fromLeft, double neighborValue) { // only allow if actually have a neighbor in that direction if (fromLeft && this.left != null) { this.leftValue = neighborValue; this.leftReceived = true; } else if (!fromLeft && this.right != null) { this.rightValue = neighborValue; this.rightReceived = true; } } /** * Method to update the average of all connected nodes, placed in run to implement * runnable interface, so that the operation can be performed in a thread. */ public void run() { // code to update node goes here /** * 1. send data value to left and right neighbors * 2. receive data from left and right neighbors * 3. compute new value using those values * 4. wait until all nodes updated before repeating */ // while (true) { sendToNeighbors(); //use interupts to wake up neighbor's threads??? if (this.left != null && this.right != null) { // can't continue until values received from both neighbors while (!this.leftReceived || !this.rightReceived) { // allow other threads to run, i.e. wait to receive data System.out.println("Node " + this.id + " waiting for data"); Thread.yield(); } // can now safely update value and reset this none's received status this.value = (this.leftValue + this.rightValue + 2.0 * this.value)/4.0; this.leftReceived =false; this.rightReceived =false; } System.out.println("Node " + this.id + " finished updating."); } public static final boolean LEFT = true; public static final boolean RIGHT = false; private String id; // an identifier for the node private double value; // value of this cell private Node left; // pointer to left neighbor private Node right; // pointer to left neighbor private double leftValue; private double rightValue; private boolean leftReceived; private boolean rightReceived; }