/* File: Counter05.java Continuing along the same theme, now the two windows are written on by two different classes. One thread tries to populate the sharedArray with sequences (squares, Fibonacci numbers). The other thread just prints out whatever is in the array. Unfortunately, the first thread is slower (has larger sleep values) than the second thread. So, the second thread ends up printing out values before the array is ready. Moral of the story: we need synchronization. */ import javax.swing.*; import java.awt.Font ; public class Counter05 { // data members are accessible to methods of inner classes. int [] sharedArray ; // These windows just print out the contents of sharedArray // over and over again. // private class Window1 implements Runnable { int xpos = 0 ; int ypos = 0 ; boolean keepRunning ; // keep going? Window1() { // do nothing } Window1(int x, int y) { xpos = x ; ypos = y ; } public void run() { try { JFrame frame = new JFrame( "Fast Display"); JLabel label = new JLabel("Hello, Java!", JLabel.CENTER ); label.setFont( new Font("Serif", Font.BOLD, 36) ) ; frame.getContentPane().add( label ); frame.setSize( 300, 300 ); frame.setLocation( xpos, ypos ); frame.setVisible( true ); keepRunning = true ; while (keepRunning) { // keep going until someone says stop! Thread.sleep(250) ; // print contents of sharedArray[] // for(int i = 0 ; i < sharedArray.length ; i++) { label.setText( Integer.toString(sharedArray[i]) ) ; Thread.sleep(400) ; } label.setText("Again! Again!") ; // Teletubies say eh-oh } // end of while(keepRunning) } catch ( InterruptedException e ) { System.out.println("Oh look! an exception!") ; } } // end of run() } // end of private class Window1 // This window tries to populate sharedArray[] with some "interesting" // sequences. // private class SequenceWindow implements Runnable { int xpos = 0 ; int ypos = 0 ; SequenceWindow() { // do nothing } SequenceWindow(int x, int y) { xpos = x ; ypos = y ; } public void run() { try { // similar set up as usual JFrame frame = new JFrame( "Sequence Window"); JLabel label = new JLabel("Hello, Java!", JLabel.CENTER ); label.setFont( new Font("Serif", Font.BOLD, 18) ) ; frame.getContentPane().add( label ); frame.setSize( 600, 300 ); // a bit wider frame.setLocation( xpos, ypos ); frame.setVisible( true ); Thread.sleep(1000) ; // Write square values (0, 1, 4, 9, 16 ...) to sharedArray[] // for(int i = 0 ; i < sharedArray.length ; i++) { sharedArray[i] = i*i ; // i squared label.setText( "Setting sharedArray[" + i + "] to " + i*i) ; Thread.sleep(2000) ; } label.setText( "Done with Squares!" ) ; Thread.sleep(2000) ; // wait a bit // Write Fibonacci numbers to sharedArray[] // sharedArray[0] = 1 ; // base cases sharedArray[1] = 1 ; for(int i = 2 ; i < sharedArray.length ; i++) { sharedArray[i] = sharedArray[i-1] + sharedArray[i-2] ; label.setText( "Setting sharedArray[" + i + "] to " + sharedArray[i]) ; Thread.sleep(2000) ; } label.setText( "Done with Fibonacci numbers!" ) ; Thread.sleep(2000) ; // wait a bit } catch ( InterruptedException e ) { System.out.println("Oh look! an exception!") ; } } } public void doThis() { // initialize sharedArray with "boring" numbers // sharedArray = new int[20] ; for (int i = 0 ; i < sharedArray.length ; i++) { sharedArray[i] = i ; } // start window that prints out sharedArray[] // Window1 w1 = new Window1() ; Thread t1 = new Thread(w1) ; t1.start() ; // start window that populates sharedArray[] with sequences // SequenceWindow w2 = new SequenceWindow(400, 0) ; Thread t2 = new Thread(w2) ; t2.start() ; try { // wait for sequences to stop t2.join() ; // tell w1 to stop w1.keepRunning = false ; // wait for w1 to stop t1.join() ; } catch ( InterruptedException e ) { System.out.println("Oh look! an exception!") ; } System.exit(0) ; } public static void main( String[] args ) { Counter05 obj = new Counter05() ; obj.doThis() ; } }