/** * Author: Josiah Yoder et al. * Class: SE2811-011 * Date: 12/16/13 8:27 AM * Lesson: Week 3, Day 1 */ package example3_1; import java.text.DecimalFormat; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Random; /** * This is a cleaned-up version of Example. * * Illustrates how to run two threads at the same time. * In this case, they both succeed, but we just got lucky. * Generally speaking, some kind of code is needed to protect against errors. * * Some renaming, some further development. */ public class ExampleCleanedUp implements Runnable{ public static final int SIZE = 2000000; // Tuned so creating list takes ~1 second. private List list; private static final DecimalFormat format = new DecimalFormat("#.#"); /** * Initializes all members so no instance variable is null. */ public ExampleCleanedUp() { // Ensure list is never null: createList(); } /** * Sorts our big list of data. * * Collections.sort sorts the collection in-place. */ public void sortList() { // O( n Log(n) ) Collections.sort(list); } /** * Checks for errors in the long list. * * If sorted, every element should be greater than or equal to the previous one. * * (May not work if NaN's or INFINITY's are in list.) */ public void checkSort() { double prev = Double.NEGATIVE_INFINITY; for(double d: list) { if(d < prev) { throw new RuntimeException("List is not sorted! Current element is: "+d+" Previous element was: "+prev); } prev = d; } } /** * Creates a long list of random numbers. */ public void createList() { list = new LinkedList(); Random generator = new Random(); for(int i = 0; i < SIZE; i++) { list.add(generator.nextDouble()); } } /** * See class description. * * @param ignored Obligatory arguments */ public static void main(String[] ignored) { long timeStarted = System.nanoTime(); ExampleCleanedUp ex = new ExampleCleanedUp(); long timeExampleFinished = System.nanoTime(); System.out.println("main: Done creating list ("+ format.format((timeExampleFinished-timeStarted)/1e9)+" s)"); // If we run checkSort() here, it throws a RuntimeException // because the array is not sorted. // ex.checkSort(); Thread thread = new Thread(ex); thread.start(); Thread thread2 = new Thread(ex); thread2.start(); for(int i = 0; i < SIZE; i++) { // Just doing some random calculation. Math.sqrt(i); // Might be more interesting if we used the // list, but at this point its a private // member of the example. } // Wait for the thread to join us. try { thread.join(); } catch(InterruptedException e) { // We are not really waiting on anything from the thread // so we don't need to do anything special here // to clean up after the interruption. System.out.println("We were interrupted"); } // For some reason, this works. // Perhaps it is because both sort algorithms start by copying the data // into a temporary array. ex.checkSort(); System.out.println("main: I'm done! Bye!"); } /** * Sorts the data, keeping track of time. */ public void run() { long timeStartedNs = System.nanoTime(); System.out.println("run "+Thread.currentThread().getId()+": Starting sorting list"); sortList(); long timeFinishedNs = System.nanoTime(); System.out.println("run "+Thread.currentThread().getId()+": Done sorting list ("+ format.format((timeFinishedNs-timeStartedNs)/1e9)+" s, "+(timeFinishedNs-timeStartedNs) + " ns)"); System.out.println("run "+Thread.currentThread().getId()+": I'm done! Bye!"); } }