package csg.ass2; import java.io.Serializable; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.Random; public class MainThread { /** * @param args */ public static void main(String[] args) { if (args.length != 4) { System.out .println("\nYou have not entered exactly 4 number of arguments."); System.exit(0); } List taskQueue = new ArrayList(); List resultQueue = new ArrayList(); int n = Integer.parseInt(args[0]); int s = Integer.parseInt(args[1]); int w = Integer.parseInt(args[2]); int t = Integer.parseInt(args[3]); Runnable runnableClassObj = new MyRunnableClass(taskQueue, resultQueue); Thread threads[] = new Thread[t]; for (int i = 0; i < t; i++) { threads[i] = new Thread(runnableClassObj); threads[i].start(); } System.out.println("Main : I started all threads"); synchronized (taskQueue) { for (int i = 0; i < w; i++) { int xOfStartPnt = (BigInteger.valueOf(new Random(i).nextInt()) .abs().intValue() % n) + 1; int yOfStartPnt = (BigInteger.valueOf( new Random(i - 1).nextInt()).abs().intValue() % n) + 1; int zOfStartPnt = (BigInteger.valueOf( new Random(i + 1).nextInt()).abs().intValue() % n) + 1; Task task = new Task(new ThreeDPoint(xOfStartPnt, yOfStartPnt, zOfStartPnt), s, n); taskQueue.add(task); taskQueue.notifyAll(); } } System.out.println("I have put all tasks w=" + w); synchronized (resultQueue) { while (resultQueue.isEmpty() || resultQueue.size() < w) { try { resultQueue.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Got entire resultqueue size of resultqueue : " + resultQueue.size()); System.out.println("\nThe results of random walks :\n"); int counter = 0; for (Result result : resultQueue) { System.out.println("\n# " + counter + " Start Point: " + result.getStartPoint().getX() + " " + result.getStartPoint().getY() + " " + result.getStartPoint().getZ()); System.out.println(" End Point: " + result.getEndpoint().getX() + " " + result.getEndpoint().getY() + " " + result.getEndpoint().getZ()); counter++; } } System.exit(0); } } class MyRunnableClass implements Runnable { List taskQueue = null; List resultQueue = null; int numberOfSteps = 0; int dimension = 0; public MyRunnableClass(List tQ, List rQ) { taskQueue = tQ; resultQueue = rQ; } @Override public void run() { while (true) { Task task = null; synchronized (taskQueue) { // System.out.println("Thread started"); while (taskQueue.isEmpty()) { try { // System.out.println("Waiting for taskQueue"); taskQueue.wait(); // System.out.println("Out of wait"); } catch (InterruptedException e) { // System.out.println("Exception while waiting"); e.printStackTrace(); } } task = taskQueue.get(0); taskQueue.remove(0); } Result result = performRandomWalk(task); synchronized (resultQueue) { resultQueue.add(result); resultQueue.notifyAll(); } } } private Result performRandomWalk(Task task) { System.out.println("Random walk started with start point:" + task.getStartPoint()); Result resultOfRandomWalk = new Result(); ThreeDPoint currentPoint = new ThreeDPoint(task.getStartPoint().getX(), task.getStartPoint().getY(), task.getStartPoint().getZ()); Random randomNumberGenerator = null; int randomNumber = 0; int rangeWidth = 0; for (int i = 0; i < task.getNumberOfSteps(); i++) { int n = task.getDimension(); int x = currentPoint.getX(); int y = currentPoint.getY(); int z = currentPoint.getZ(); int rangeStart = 0; randomNumberGenerator = new Random(i); randomNumber = randomNumberGenerator.nextInt(); randomNumber = BigInteger.valueOf(randomNumber).abs().intValue(); randomNumber = randomNumber % (BigInteger.valueOf(task.getDimension()).pow(3) .intValue()); rangeWidth = x * (n - y) * (n - z); if (rangeStart <= randomNumber && randomNumber < (rangeStart + rangeWidth)) { if (currentPoint.getX() < n) { currentPoint.setX(currentPoint.getX() + 1); } } else { rangeStart = rangeStart + rangeWidth; rangeWidth = (n - x) * y * z; if (rangeStart <= randomNumber && randomNumber < (rangeStart + rangeWidth)) { if (currentPoint.getX() > 1) { currentPoint.setX(currentPoint.getX() - 1); } } else { rangeStart = rangeStart + rangeWidth; rangeWidth = (n - x) * y * (n - z); if (rangeStart <= randomNumber && randomNumber < (rangeStart + rangeWidth)) { if (currentPoint.getY() < n) { currentPoint.setY(currentPoint.getY() + 1); } } else { rangeStart = rangeStart + rangeWidth; rangeWidth = x * (n - y) * z; if (rangeStart <= randomNumber && randomNumber < (rangeStart + rangeWidth)) { if (currentPoint.getY() > 1) { currentPoint.setY(currentPoint.getY() - 1); } } else { rangeStart = rangeStart + rangeWidth; rangeWidth = (n - x) * (n - y) * z; if (rangeStart <= randomNumber && randomNumber < (rangeStart + rangeWidth)) { if (currentPoint.getZ() < n) { currentPoint.setZ(currentPoint.getZ() + 1); } } else { rangeStart = rangeStart + rangeWidth; rangeWidth = x * y * (n - z); if (rangeStart <= randomNumber && randomNumber < (rangeStart + rangeWidth)) { if (currentPoint.getZ() > 1) { currentPoint .setZ(currentPoint.getZ() - 1); } } } } } } } } resultOfRandomWalk.setStartPoint(task.getStartPoint()); resultOfRandomWalk.setEndpoint(currentPoint); return resultOfRandomWalk; } } class ThreeDPoint implements Serializable { /** * */ private static final long serialVersionUID = 1L; private int x; private int y; private int z; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getZ() { return z; } public void setZ(int z) { this.z = z; } public ThreeDPoint(int x, int y, int z) { super(); this.x = x; this.y = y; this.z = z; } public String toString() { String retString = new String(); retString = retString + "x=" + x + " y=" + y + " z=" + z; return retString; } } class Task implements Serializable { /** * */ private static final long serialVersionUID = 1L; private ThreeDPoint startPoint = null; private int numberOfSteps; private int dimension; public Task(ThreeDPoint startPnt, int noOfSteps, int dim) { super(); startPoint = startPnt; this.numberOfSteps = noOfSteps; this.dimension = dim; } public int getNumberOfSteps() { return numberOfSteps; } public void setNumberOfSteps(int numberOfSteps) { this.numberOfSteps = numberOfSteps; } public int getDimension() { return dimension; } public void setDimension(int dimension) { this.dimension = dimension; } public ThreeDPoint getStartPoint() { return startPoint; } public void setStartPoint(ThreeDPoint startPoint) { this.startPoint = startPoint; } } class Result implements Serializable { /** * */ private static final long serialVersionUID = 1L; private ThreeDPoint startPoint; private ThreeDPoint endpoint; public ThreeDPoint getStartPoint() { return startPoint; } public void setStartPoint(ThreeDPoint startPoint) { this.startPoint = startPoint; } public ThreeDPoint getEndpoint() { return endpoint; } public void setEndpoint(ThreeDPoint endpoint) { this.endpoint = endpoint; } }