package def;

/** 
 * Goetz
 * slightly modified: smh 11/17/09, 04/08/2014	
 * Creates SIZE threads to search for the maximum value of a large matrix. 
 * Each thread searches one row of the matrix. 
 */ 

public class TenThreads { 
	
	static int SIZE = 1000;		// don't go much bigger -- takes too long
	
	private static class WorkerThread extends Thread { 
		int max = Integer.MIN_VALUE; 
		int[] ourArray; 
		
		public WorkerThread(int[] ourArray) { 
			this.ourArray = ourArray; 
		} 
		// Find the maximum value in our particular piece of the array 
		public void run() { 
			
			for (int i = 0; i < ourArray.length; i++) { 
				max = Math.max(max, ourArray[i]); 
				if (SIZE <= 10) System.out.println("thread id: " + getId());
				try {
					sleep(0, 1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} 

		public int getMax() { 
			return max; 
		} 
	} 
	
	// for demo purposes, call getBigMatrix()  OR  getBigMatrixRandom()
	private static int[][] getBigMatrix() {
		int[][] matrix = new int[SIZE][SIZE];
		for (int r=0; r<SIZE; r++) 
			for (int c=0; c<SIZE; c++)
				matrix[r][c] = -1;
		
		int row = (int) (Math.random() * SIZE); System.out.println("row: " + row);
		int col = (int) (Math.random() * SIZE); System.out.println("col: " + col);
		matrix[row][col] = 9;
		
		return matrix;
		
	}
	
	// for demo purposes. Call getBigMatrix()  OR  getBigMatrixRandom()
	private static int[][] getBigMatrixRandom() {
		int[][] matrix = new int[SIZE][SIZE];
		for (int r=0; r<SIZE; r++) 
			for (int c=0; c<SIZE; c++)
				matrix[r][c] = (int) (Math.random() * SIZE);
		
		/* pick a random location to stuff the largest value */
		int row = (int) (Math.random() * SIZE); System.out.println("row: " + row);
		int col = (int) (Math.random() * SIZE); System.out.println("col: " + col);
		matrix[row][col] = SIZE;
		
		return matrix;
		
	}

	public static void main(String[] args) { 
		WorkerThread[] threads = new WorkerThread[SIZE]; 
		int[][] bigMatrix = getBigMatrixRandom();            // or call getBigMatrix() to have -1's
		
		/* code to print small matrix */
		if (SIZE <=10)
			for (int r=0; r<SIZE; r++) {
				for (int c=0; c<SIZE; c++) 
					System.out.print(bigMatrix[r][c] + " ");
				System.out.println();
			}
		
		int max = Integer.MIN_VALUE; 

		// Give each thread a horizontal slice of the matrix to work with 
		for (int i=0; i < SIZE; i++) { 
			threads[i] = new WorkerThread(bigMatrix[i]); 
			threads[i].start(); 
		} 

		// Wait for each thread to finish , update max from threads' work
		try { 
			for (int i=0; i < SIZE; i++) { 
				threads[i].join(); 
				max = Math.max(max, threads[i].getMax()); 
			} 
		} 
		catch (InterruptedException e) { 
			// fall through 
		} 
		
		System.out.println("Maximum value was " + max); 
	} 
} 

