home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / code / ch04.txt < prev    next >
Text File  |  1998-12-14  |  35KB  |  1,723 lines

  1. Clock.java:
  2.  
  3. import java.awt.*;
  4. import java.applet.*;
  5. import java.util.*;
  6. import java.text.*;
  7.  
  8. /*
  9.  * class for applet/application
  10.  */
  11. public class Clock extends Applet implements Runnable {
  12.  
  13. /*
  14.  * the instance of Thread for checking the time periodically
  15.  */
  16. Thread thread = null;
  17. SimpleDateFormat formatter;
  18. Date currentDate;
  19.  
  20. /*
  21.  * saved values used to draw only when things have changed
  22.  */
  23. int lastxs=0;
  24. int lastys=0;
  25. int lastxm=0;
  26. int lastym=0;
  27. int lastxh=0;
  28. int lastyh=0;
  29.  
  30. /**
  31.   * sets the background color to light gray
  32.   */
  33. public void init(){
  34.         this.setBackground(Color.lightGray);
  35. }
  36.  
  37. /**
  38.  * draws the clock face
  39.  * @param g - destination graphics object
  40.  */
  41. public void paint (Graphics g) {
  42.  
  43.        int xh, yh, xm, ym, xs, ys, s=0,m=10, h=10, xcenter, ycenter;
  44. String Today;
  45.     currentDate = new Date();
  46.     SimpleDateFormat formatter = new SimpleDateFormat("s",Locale.getDefault());
  47. try{
  48.         s=Integer.parseInt(formatter.format(currentDate));
  49.     }catch(NumberFormatException n){
  50.         s=0;
  51.     }
  52.  
  53.     formatter.applyPattern("m");
  54.     try{
  55.         m=Integer.parseInt(formatter.format(currentDate));
  56.     }catch(NumberFormatException n){
  57.         m=10; 
  58.     }
  59.  
  60.     formatter.applyPattern("h");
  61.     try{
  62.         h=Integer.parseInt(formatter.format(currentDate));
  63.     }catch(NumberFormatException n){
  64.         h=10;
  65.     }
  66.  
  67.        xcenter=100;
  68.        ycenter=100;
  69.  
  70.        xs = (int)(Math.cos(s * 3.14f/30 - 3.14f/2) * 45 + xcenter);
  71. ys = (int)(Math.sin(s * 3.14f/30 - 3.14f/2) * 45 + ycenter);
  72. xm = (int)(Math.cos(m * 3.14f/30 - 3.14f/2) * 40 + xcenter);
  73. ym = (int)(Math.sin(m * 3.14f/30 - 3.14f/2) * 40 + ycenter);
  74. xh = (int)(Math.cos((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 30
  75. + xcenter);
  76.        yh = (int)(Math.sin((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 30
  77. + ycenter);
  78.  
  79. // Draw the circle and numbers
  80.        g.setFont(new Font("TimesRoman", Font.PLAIN, 14));
  81.        g.setColor(Color.blue);
  82.        g.drawOval (xcenter-50, ycenter-50, 100, 100);
  83.        g.setColor(Color.darkGray);
  84.        g.drawString("9",xcenter-45,ycenter+3);
  85.        g.drawString("3",xcenter+40,ycenter+3);
  86.        g.drawString("12",xcenter-5,ycenter-37);
  87.        g.drawString("6",xcenter-3,ycenter+45);
  88.  
  89. // Erase if necessary, and redraw
  90.        g.setColor(Color.lightGray);
  91.        if (xs != lastxs || ys != lastys) {
  92.               g.drawLine(xcenter, ycenter, lastxs, lastys);
  93.        }
  94.        if (xm != lastxm || ym != lastym) {
  95.               g.drawLine(xcenter, ycenter-1, lastxm, lastym);
  96.               g.drawLine(xcenter-1, ycenter, lastxm, lastym);
  97.        }
  98.        if (xh != lastxh || yh != lastyh) {
  99.               g.drawLine(xcenter, ycenter-1, lastxh, lastyh);
  100.               g.drawLine(xcenter-1, ycenter, lastxh, lastyh);
  101.        }
  102.  
  103.        g.setColor(Color.darkGray);
  104.        g.drawLine(xcenter, ycenter, xs, ys);
  105.        g.setColor(Color.red);
  106.        g.drawLine(xcenter, ycenter-1, xm, ym);
  107.        g.drawLine(xcenter-1, ycenter, xm, ym);
  108.        g.drawLine(xcenter, ycenter-1, xh, yh);
  109.        g.drawLine(xcenter-1, ycenter, xh, yh);
  110.        lastxs=xs; lastys=ys;
  111.        lastxm=xm; lastym=ym;
  112.        lastxh=xh; lastyh=yh;
  113. }
  114.  
  115. /*
  116.  * called when the applet is started
  117.  * create a new instance of Thread and start it
  118.  */
  119. public void start() {
  120.  
  121.        if(thread == null) {
  122.               thread = new Thread(this);
  123.               thread.start();
  124.        }
  125. }
  126.  
  127. /*
  128.  * called when the applet is stopped
  129.  * stops the thread
  130.  */
  131. public void stop() {
  132.  
  133.        thread = null;
  134. }
  135.  
  136. /*
  137.  * the thread itself
  138.  * sleeps for 100ms and forces a repaint
  139.  */
  140. public void run() {
  141.  
  142.        while (thread != null) {
  143.               try {
  144.                      Thread.sleep(100);
  145.               } catch (InterruptedException e) { }
  146.               repaint();
  147.        }
  148.        thread = null;
  149. }
  150.  
  151. /**
  152.  * override the default update method to avoid flickering
  153.  * caused by unnecessary erasing of the applet panel
  154.  * @param g - destination graphics object
  155.  */
  156. public void update(Graphics g) {
  157.        paint(g);
  158. }
  159.  
  160. /**
  161.  * application entry point
  162.  * not used when run as an applet
  163.  * create a new window frame and add the applet inside
  164.  * @param args[] - command-line arguments
  165.  */
  166. public static void main (String args[]) {
  167.  
  168.        Frame f = new Frame ("Clock");
  169.        Clock clock = new Clock ();
  170.  
  171.        f.setSize (210, 230);
  172.        f.add ("Center", clock);
  173.        f.show ();
  174.        clock.init ();
  175.        clock.start ();
  176. }
  177. }
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186. MultiThread.java:
  187.  
  188. import java.applet.Applet;
  189. import java.awt.*;
  190.  
  191. /**
  192.  * class LineColors holds 24 color values
  193.  */
  194. class LineColors {
  195.  
  196. /**
  197.  * color[] array holds the colors to be used
  198.  */
  199. Color color[];
  200.  
  201. /**
  202.  * class constructor
  203.  * initializes the color array using an arbitrary algorithm
  204.  */
  205. public LineColors () {
  206.        color = new Color[24];
  207.        int i, rgb;
  208.  
  209.        rgb = 0xff;
  210.        for (i=0; i<24; i+=1) {
  211.               color[i] = new Color (rgb);
  212.               rgb <<= 1;
  213.               if ((rgb & 0x1000000) != 0) {
  214.                      rgb |= 1;
  215.                      rgb &= 0xffffff;
  216.               }
  217.        }
  218. }
  219. }
  220.  
  221. /**
  222.  * class describing one line segment
  223.  */
  224. class Segment {
  225.  
  226. /*
  227.  * x1, y1 - starting coordinates for this segment
  228.  * x2, y2 - ending coordinates for this segment
  229.  * dx1,...dy2 - velocities for the endpoints
  230.  * whichcolor - the current index into color array
  231.  * width, height - width and height of bounding panel
  232.  * LC - instance of LineColors class
  233.  */
  234. double x1, y1, x2, y2;
  235. double dx1, dy1, dx2, dy2;
  236. int whichcolor, width, height;
  237. LineColors LC;
  238.  
  239. /**
  240.  * class constructor
  241.  * initialize endpoints and velocities to random values
  242.  * @param w - width of bounding panel
  243.  * @param h - height of bounding panel
  244.  * @param c - starting color index
  245.  * @param lc - instance of LineColors class
  246.  */
  247. public Segment (int w, int h, int c, LineColors lc) {
  248.  
  249.        whichcolor = c;
  250.        width = w;
  251.        height = h;
  252.        LC = lc;
  253.        x1 = (double) w * Math.random ();
  254.        y1 = (double) h * Math.random ();
  255.        x2 = (double) w * Math.random ();
  256.        y2 = (double) h * Math.random ();
  257.  
  258.        dx1 = 5 - 10 * Math.random ();
  259.        dy1 = 5 - 10 * Math.random ();
  260.        dx2 = 5 - 10 * Math.random ();
  261.        dy2 = 5 - 10 * Math.random ();
  262. }
  263.  
  264. /*
  265.  * increment color index
  266.  * calculate the next endpoint position for this segment
  267.  */
  268. void compute () {
  269.  
  270.        whichcolor += 1;
  271.        whichcolor %= 24;
  272.        
  273.        x1 += dx1;
  274.        y1 += dy1;
  275.        x2 += dx2;
  276.        y2 += dy2;
  277.  
  278.        if (x1 < 0 || x1 > width) dx1 = -dx1;
  279.        if (y1 < 0 || y1 > height) dy1 = -dy1;
  280.        if (x2 < 0 || x2 > width) dx2 = -dx2;
  281.        if (y2 < 0 || y2 > height) dy2 = -dy2;
  282. }
  283.  
  284. /**
  285.  * draw the line segment using the current color
  286.  * @param g - destination graphics object
  287.  */
  288. void paint (Graphics g) {
  289.  
  290.        g.setColor (LC.color [whichcolor]);
  291.        g.drawLine ((int) x1, (int) y1, (int) x2, (int) y2);
  292. }
  293. }
  294.  
  295. /**
  296.  * The applet/application proper
  297.  */
  298. class Lines extends Panel implements Runnable {
  299.  
  300. /*
  301.  * width, height - width and height of bounding panel
  302.  * Nlines - number of line segments to be displayed
  303.  * lines - array of instances of Segment class
  304.  * LC - instance of LineColors class
  305.  */
  306. int width, height;
  307. final int NLines = 4;
  308. Segment lines[] = new Segment[NLines];
  309. LineColors LC = new LineColors ();
  310.  
  311. /*
  312.  * instance of thread for this line
  313.  */
  314. Thread thread;
  315.  
  316. /**
  317.  * init is called when the applet is loaded
  318.  * save the width and height
  319.  * create instances of Segment class
  320.  */
  321. public void init () {
  322.  
  323.        
  324.        width = 200;
  325.        height = 200;
  326.        
  327.        thread = new Thread (this);
  328.        thread.start ();
  329.  
  330.        int i;
  331.  
  332.       for (i=0; i<NLines; i+=1)
  333.               lines[i] = new Segment (width, height, (2*i) % 24, LC);
  334. }
  335.  
  336. /**
  337.  * recompute the next endpoint coordinates for each line
  338.  * invoke paint() method for each line
  339.  * @param g - destination graphics object
  340.  */
  341. public void paint (Graphics g) 
  342. {
  343.  
  344.        int i; 
  345.        g.setColor (Color.black);
  346.        g.drawRect (0, 0, width-1, height-1);
  347.        for (i=0; i<NLines; i+=1) {
  348.               lines[i].compute ();
  349.               lines[i].paint (g);
  350.        }
  351. }
  352.  
  353. /*
  354.  * the thread proper
  355.  * calls paint() every 50ms
  356.  */
  357. public void run()
  358. {
  359.        Graphics g = getGraphics();
  360.        while (true) {
  361.               paint (g);
  362.               try {
  363.                      Thread.sleep (50);
  364.               } catch(InterruptedException e) { }
  365.        }
  366. }
  367. }
  368.  
  369. /*
  370.  * the applet/application proper
  371.  * creates two instances of Lines and starts them
  372.  * as separate threads
  373.  */
  374. public class MultiThread extends Applet {
  375.  
  376. /*
  377.  * the instances of Lines
  378.  */
  379. Lines lines1; 
  380. Lines lines2;
  381.  
  382. /*
  383.  * called when the applet is loaded
  384. */
  385. public void init () {
  386.  
  387.        setLayout (new GridLayout (2, 1, 0, 0));
  388.  
  389.        lines1 = new Lines ();
  390.        lines2 = new Lines ();
  391.        add (lines1);
  392.        add (lines2); 
  393.        lines1.setSize (200, 100);
  394.        lines2.setSize (200, 100);
  395.        lines1.init ();
  396.        lines2.init ();
  397. }
  398.  
  399. /**
  400.  * application entry point, unused when run as an applet
  401.  * create window frame and add applet inside
  402.  * @param args[] - command-line arguments
  403.  */
  404. public static void main (String args[]) {
  405.  
  406.        Frame f = new Frame ("Colored lines"); 
  407.        f.setLayout (new GridLayout (2, 1, 0, 0));
  408.  
  409.        f.setSize (200, 200);
  410.  
  411.        Lines lines1 = new Lines ();
  412.        Lines lines2 = new Lines ();
  413.        f.add (lines1);
  414.        f.add (lines2);
  415.        f.show ();
  416.        lines1.init ();
  417.        lines2.init ();
  418. }
  419. }
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427. MultiThread.java:
  428.  
  429. import java.applet.Applet;
  430. import java.awt.*;
  431.  
  432. /**
  433.  * class LineColors holds 24 color values
  434.  */
  435. class LineColors {
  436.  
  437. /**
  438.  * color[] array holds the colors to be used
  439.  */
  440. Color color[];
  441.  
  442. /**
  443.  * class constructor
  444.  * initializes the color array by using an arbitrary algorithm
  445.  */
  446. public LineColors () {
  447.        color = new Color[24];
  448.        int i, rgb;
  449.  
  450.        rgb = 0xff;
  451.        for (i=0; i<24; i+=1) {
  452.               color[i] = new Color (rgb);
  453.               rgb <<= 1;
  454.               if ((rgb & 0x1000000) != 0) {
  455.                      rgb |= 1;
  456.                      rgb &= 0xffffff;
  457.               }
  458.        }
  459. }
  460. }
  461.  
  462. /**
  463.  * class describing one line segment
  464.  */
  465. class Segment {
  466.  
  467. /*
  468.  * x1, y1 - starting coordinates for this segment
  469.  * x2, y2 - ending coordinates for this segment
  470.  * dx1,...dy2 - velocities for the endpoints
  471.  * whichcolor - the current index into color array
  472.  * width, height - width and height of bounding panel
  473.  * LC - instance of LineColors class
  474.  */
  475. double x1, y1, x2, y2;
  476. double dx1, dy1, dx2, dy2;
  477. int whichcolor, width, height;
  478. LineColors LC;
  479.  
  480. /**
  481.  * class constructor
  482.  * initialize endpoints and velocities to random values
  483.  * @param w - width of bounding panel
  484.  * @param h - height of bounding panel
  485.  * @param c - starting color index
  486.  * @param lc - instance of LineColors class
  487.  */
  488. public Segment (int w, int h, int c, LineColors lc) {
  489.  
  490.        whichcolor = c;
  491.        width = w;
  492.        height = h;
  493.        LC = lc;
  494.        x1 = (double) w * Math.random ();
  495.        y1 = (double) h * Math.random ();
  496.        x2 = (double) w * Math.random ();
  497.        y2 = (double) h * Math.random ();
  498.  
  499.        dx1 = 5 - 10 * Math.random ();
  500.        dy1 = 5 - 10 * Math.random ();
  501.        dx2 = 5 - 10 * Math.random ();
  502.        dy2 = 5 - 10 * Math.random ();
  503. }
  504.  
  505. /*
  506.  * increment color index
  507.  * calculate the next endpoint position for this segment
  508.  */
  509. void compute () {
  510.  
  511.        whichcolor += 1;
  512.        whichcolor %= 24;
  513.        
  514.        x1 += dx1;
  515.        y1 += dy1;
  516.        x2 += dx2;
  517.        y2 += dy2;
  518.  
  519.        if (x1 < 0 || x1 > width) dx1 = -dx1;
  520.        if (y1 < 0 || y1 > height) dy1 = -dy1;
  521.        if (x2 < 0 || x2 > width) dx2 = -dx2;
  522.        if (y2 < 0 || y2 > height) dy2 = -dy2;
  523. }
  524.  
  525. /**
  526.  * draw the line segment using the current color
  527.  * @param g - destination graphics object
  528.  */
  529. void paint (Graphics g) {
  530.  
  531.        g.setColor (LC.color [whichcolor]);
  532.        g.drawLine ((int) x1, (int) y1, (int) x2, (int) y2); 
  533. }
  534. }
  535.  
  536. /**
  537.  * The applet/application proper
  538.  */
  539. class Lines extends Panel implements Runnable {
  540.  
  541. /*
  542.  * width, height - width and height of bounding panel
  543.  * Nlines - number of line segments to be displayed
  544.  * lines - array of instances of Segment class
  545.  * LC - instance of LineColors class
  546.  */
  547. int width, height;
  548. final int NLines = 4;
  549. Segment lines[] = new Segment[NLines];
  550. LineColors LC = new LineColors ();
  551.  
  552. /*
  553.  * instance of thread for this line
  554.  */
  555. Thread thread;
  556.  
  557. /**
  558.  * init is called when the applet is loaded
  559.  * save the width and height
  560.  * create instances of Segment class
  561.  */
  562. public void init (int inPriority) {
  563.  
  564.        
  565.        width = 200;
  566.        height = 200;
  567.        
  568.        thread = new Thread (this);
  569.        thread.start ();
  570.        thread.setPriority(inPriority);
  571.  
  572.        int i;
  573.        for (i=0; i<NLines; i+=1)
  574.               lines[i] = new Segment (width, height, (2*i) % 24, LC);
  575. }
  576.  
  577. /**
  578.  * recompute the next endpoint coordinates for each line
  579.  * invoke paint() method for each line
  580.  * @param g - destination graphics object
  581.  */
  582. public void paint (Graphics g) 
  583. {
  584.  
  585.        int i;
  586.        g.setColor (Color.black);
  587.        g.drawRect (0, 0, width-1, height-1);
  588.        for (i=0; i<NLines; i+=1) {
  589.               lines[i].compute ();
  590.               lines[i].paint (g);
  591.        }
  592. }
  593.  
  594. /*
  595.  * the thread proper
  596.  * calls paint() every 50ms
  597.  */
  598. public void run()
  599. {       
  600.  
  601.        Graphics g = getGraphics();
  602.        int iterCount = 0;
  603.        while (true) {
  604.               paint(g);
  605.               try {
  606.                      iterCount += 1;
  607.                      if (iterCount == 5) {
  608.                             Thread.sleep(10);
  609.                             iterCount = 0;
  610.                      }
  611.               }
  612.               catch (InterruptedException e) {
  613.                      System.out.println("Caught exception...");
  614. }
  615.        }
  616. }
  617. }
  618.  
  619. /*
  620.  * the applet/application proper
  621.  * creates two instances of Lines and starts them
  622.  * as separate threads
  623.  */
  624. public class MultiThread extends Applet {
  625.  
  626. /*
  627.  * the instances of Lines
  628.  */
  629. Lines lines[];
  630.  
  631. /*
  632.  * the number of threads to be run
  633.  */
  634. public final static int NumThreads = 5;
  635.  
  636. /*
  637.  * the priority of the first thread
  638.  */
  639. public final static int StartingPriority = Thread.NORM_PRIORITY;
  640.  
  641. /*
  642.  * called when the applet is loaded
  643.  * creates several instances of Lines and adds them to the
  644.  * applet panel
  645.  * sets the priority of each thread to 1 less than the previous
  646.  * one
  647.  */
  648. public void init () {
  649.  
  650.        setLayout (new GridLayout (MultiThread.NumThreads, 1, 0, σ0));
  651.        lines = new Lines[MultiThread.NumThreads];
  652.  
  653.        for (int i = 0; i< MultiThread.NumThreads; i++) {
  654.               lines[i] = new Lines ();
  655.               add (lines[i]);
  656.               lines[i].setSize (200, 200/MultiThread.NumThreads);
  657.               lines[i].init (StartingPriority-i);
  658.        }
  659. }
  660.  
  661. /**
  662.  * application entry point, unused when run as an applet
  663.  * create window frame and add applet inside
  664.  * @param args[] - command-line arguments
  665.  */
  666. public static void main (String args[]) {
  667.  
  668.        Frame f = new Frame ("Colored lines"); 
  669.        f.setLayout (new GridLayout (MultiThread.NumThreads, 1, 0, 0));
  670.  
  671.        f.setSize (200, 200);
  672.        Lines lines[] = new Lines[MultiThread.NumThreads];
  673.        
  674.        for (int i = 0; i< MultiThread.NumThreads; i++) {
  675.               lines[i] = new Lines ();
  676.               f.add (lines[i]); 
  677.        }
  678.  
  679.        f.show ();
  680.  
  681.        for (int i = 0; i< MultiThread.NumThreads; i++) {
  682.               lines[i].init (StartingPriority-i);
  683.        }
  684. }
  685. }
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694. SyncMethod.java:
  695.  
  696. import java.awt.*;
  697. import java.applet.Applet;
  698.  
  699. /*
  700.  * a class for handling first in, first out data structure
  701.  */
  702. class FIFO {
  703.  
  704. /*
  705.  * the maximum depth of the FIFO
  706.  */
  707. final int MaxDepth = 200;
  708.  
  709. /*
  710.  * the real depth of this FIFO
  711.  */
  712. int depth;
  713.  
  714. /*
  715.  * write and read indexes into the data array
  716.  */
  717. int writeIndex;
  718. int readIndex;
  719.  
  720. /*
  721.  * the number of data items currently in the FIFO
  722.  */
  723. int nItems;
  724.  
  725. /*
  726.  * the data proper
  727.  */
  728. int data[] = new int[MaxDepth];
  729.  
  730. /*
  731.  * width and height of the FIFO graphical display
  732.  */
  733. int width;
  734. int height;
  735.  
  736. /*
  737.  * x and y position of the upper-left corner of the FIFO
  738.  * graphical display
  739.  */
  740. int xpos;
  741. int ypos;
  742.  
  743. /**
  744.  * the constructor
  745.  * @param d - depth of the FIFO
  746.  */
  747. public FIFO (int d) {
  748.  
  749.        depth = d;
  750.        writeIndex = 0;
  751.        readIndex = 0;
  752.        nItems = 0;
  753.  
  754.        width = depth + 4;
  755.        height = 50;
  756.        xpos = 50;
  757.        ypos = 75; 
  758. }
  759.  
  760. /**
  761.  * write one integer value into the FIFO
  762.  * @param value - the value to write
  763.  */
  764. synchronized void write (int value) {
  765.  
  766.        if (nItems >= depth) return; 
  767.  
  768.        data[writeIndex] = value;
  769.        writeIndex += 1;
  770.        writeIndex %= depth;
  771.        nItems += 1;
  772. }
  773.  
  774. /**
  775.  * read 1 integer value from the FIFO
  776.  */
  777. synchronized int read () {
  778.  
  779.        if (nItems < 1) return 0;
  780.  
  781.        int value = data[readIndex]; 
  782.        readIndex += 1;
  783.        readIndex %= depth;
  784.        nItems -= 1;
  785.  
  786.        return value;
  787. }
  788.  
  789. /**
  790.  * returns true if the FIFO is empty
  791.  */
  792. synchronized boolean empty () {
  793.  
  794.        return nItems > 0 ? false : true;
  795. }
  796.  
  797. /**
  798.  * returns true if the FIFO is half full
  799.  */
  800. synchronized boolean halfFull () {
  801.  
  802.        return nItems > (depth >> 1) ? true : false;
  803. }
  804.  
  805. /**
  806.  * returns true if the FIFO is full
  807.  */
  808. synchronized boolean full () {
  809.  
  810.        return nItems >= (depth) ? true : false;
  811. }
  812.  
  813. /**
  814.  * draws the FIFO graphical display
  815.  * @param g - destination graphics context
  816.  */
  817. synchronized void paint (Graphics g) {
  818.  
  819.        int x, y, w, h;
  820.  
  821.        g.setColor (Color.white);
  822.        g.fillRect (xpos, ypos, width, height); 
  823.        g.setColor (Color.black);
  824.        g.drawRect (xpos, ypos, width, height);
  825.  
  826.        x = writeIndex + xpos + 2;
  827.        y = ypos - 22;
  828.        g.drawLine (x, y, x, y + 20);
  829.        g.drawString ("Write index "+writeIndex, x+2, y+10);
  830.  
  831.        x = readIndex + xpos + 2;
  832.        y = ypos + height + 22;
  833.        g.drawLine (x, y-20, x, y);
  834.        g.drawString ("Read index "+readIndex, x+2, y);
  835.  
  836.        if (nItems < 1) return;
  837.  
  838.        if (nItems > (depth>>1)) g.setColor (Color.red);
  839.        else g.setColor (Color.green); 
  840.  
  841.        x = xpos + 2 + readIndex;
  842.        y = ypos + 2;
  843.        if (writeIndex > readIndex) w = nItems;
  844.        else w = width - readIndex - 4;
  845.        h = height - 4;
  846.        g.fillRect (x, y, w, h);
  847.  
  848.        if (writeIndex > readIndex) return;
  849.  
  850.        x = xpos + 2;
  851.        w = writeIndex;
  852.        g.fillRect (x, y, w, h); 
  853. }
  854. }
  855.  
  856. /*
  857.  * a class that generates data continuously
  858.  */
  859. class Source extends Thread {
  860.  
  861. /*
  862.  * the FIFO to write into
  863.  */
  864. FIFO fifo;
  865. int value;
  866.  
  867. /**
  868.  * constructor
  869.  * saves the FIFO instance and starts the thread
  870.  * @param f - an instance of FIFO
  871.  */
  872. public Source (FIFO f) {
  873.  
  874.        fifo = f;
  875.        value = 0;
  876.  
  877.        start ();
  878. }
  879.  
  880. /*
  881.  * the thread that writes one word every 100ms
  882.  */
  883. public void run () {
  884.  
  885.        while (true) {
  886.               if (fifo.full() == false)
  887.                      fifo.write (value++);
  888.  
  889.               try {
  890.                      Thread.sleep (100);
  891.               } catch (InterruptedException e) {
  892.               }
  893.        }
  894. }
  895. }
  896.  
  897. /*
  898.  * a class that reads data from the FIFO
  899.  */
  900. class Sink extends Thread {
  901.  
  902. /*
  903.  * the FIFO to read from
  904.  */
  905. FIFO fifo;
  906. int value;
  907.  
  908. /**
  909.  * constructor
  910.  * saves the FIFO instance and starts the thread
  911.  * @param f - an instance of FIFO
  912.  */
  913. public Sink (FIFO f) {
  914.  
  915.        fifo = f;
  916.  
  917.        start ();
  918. }
  919.  
  920. /*
  921.  * the thread that reads all data out after the FIFO is half
  922.  * full
  923.  */
  924. public void run () {
  925.  
  926.        while (true) {
  927.               if (fifo.halfFull()) {
  928.                      try {
  929.                             Thread.sleep (1000);
  930.                      } catch (InterruptedException e) {
  931.                      }
  932.                      while (fifo.empty() == false) {
  933.                             value = fifo.read ();
  934.                             try {
  935.                                    Thread.sleep (50);
  936.                             } catch (InterruptedException e) {
  937.                             }
  938.                      }
  939.               }
  940.  
  941.               try {
  942.                      Thread.sleep (100);
  943.               } catch (InterruptedException e) {
  944.               }
  945.        }
  946. }
  947. }
  948.  
  949. /*
  950.  * the applet/application class
  951.  */
  952. public class SyncMethod extends Applet implements Runnable {
  953.  
  954. Source source;
  955. Sink sink;
  956. FIFO fifo;
  957. Thread thread;
  958.  
  959. /*
  960.  * called when the applet is loaded
  961.  * create instances of FIFO, Source, Sink, and Thread
  962.  */
  963. public void init () {
  964.  
  965.        fifo = new FIFO (200);
  966.        source = new Source (fifo);
  967.        sink = new Sink (fifo);
  968.  
  969.        thread = new Thread (this);
  970. }
  971.  
  972. /*
  973.  * start the graphics update thread
  974.  */
  975. public void start () {
  976.  
  977.        thread.start ();
  978. }
  979.  
  980. /*
  981.  * the graphics update thread
  982.  * call repaint every 100ms
  983.  */
  984. public void run () {
  985.  
  986.        while (true) {
  987.               repaint ();
  988.               try {
  989.                      Thread.sleep (100);
  990.               } catch (InterruptedException e) {
  991.               }
  992.        }
  993. }
  994.  
  995. /**
  996.  * called from update() in response to repaint()
  997.  * @param g - destination graphics context
  998.  */
  999. public void paint (Graphics g) {
  1000.  
  1001.        fifo.paint (g);
  1002. }
  1003.  
  1004. /**
  1005.  * main() is the application entry point
  1006.  * main() is unused when run as an applet
  1007.  * create a window frame and add the applet inside
  1008.  * @param args[] - command-line arguments
  1009.  */
  1010. public static void main (String args[]) {
  1011.  
  1012.        Frame f = new Frame ("Synchronized methods example");
  1013.  
  1014.        SyncMethod syncMethod = new SyncMethod ();
  1015.        f.add ("Center", syncMethod);
  1016.        f.setSize (400, 200);
  1017.        f.show ();
  1018.        
  1019.        syncMethod.init ();
  1020.        syncMethod.start ();
  1021. }
  1022. }
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032. SyncCode.java:
  1033.  
  1034. import java.awt.*;
  1035. import java.applet.Applet;
  1036.  
  1037. /*
  1038.  * a class for handling first in, first out data structure
  1039.  */
  1040. class FIFO {
  1041.  
  1042. /*
  1043.  * the maximum depth of the FIFO
  1044.  */
  1045. final int MaxDepth = 200;
  1046.  
  1047. /*
  1048.  * the real depth of this FIFO
  1049.  */
  1050. int depth;
  1051.  
  1052. /*
  1053.  * write and read indexes into the data array
  1054.  */
  1055. int writeIndex;
  1056. int readIndex;
  1057.  
  1058. /*
  1059.  * the number of data items currently in the FIFO
  1060.  */
  1061. int nItems;
  1062.  
  1063. /*
  1064.  * the data proper
  1065.  */
  1066. int data[] = new int[MaxDepth];
  1067.  
  1068. /*
  1069.  * width and height of the FIFO graphical display
  1070.  */
  1071. int width;
  1072. int height;
  1073.  
  1074. /*
  1075.  * x and y position of the upper-left corner of the FIFO
  1076.  * graphical display
  1077.  */
  1078. int xpos;
  1079. int ypos;
  1080.  
  1081. /**
  1082.  * the constructor
  1083.  * @param d - depth of the FIFO
  1084.  */
  1085. public FIFO (int d) {
  1086.  
  1087.        depth = d;
  1088.        writeIndex = 0;
  1089.        readIndex = 0;
  1090.        nItems = 0;
  1091.  
  1092.        width = depth + 4;
  1093.        height = 50;
  1094.        xpos = 50;
  1095.        ypos = 75; 
  1096. }
  1097.  
  1098. /**
  1099.  * write one integer value into the FIFO
  1100.  * @param value - the value to write
  1101.  */
  1102. void write (int value) {
  1103.  
  1104.        if (nItems >= depth) return;
  1105.  
  1106.        data[writeIndex] = value;
  1107.        writeIndex += 1;
  1108.        writeIndex %= depth;
  1109.        nItems += 1;
  1110. }
  1111.  
  1112. /**
  1113.  * read one integer value from the FIFO
  1114.  */
  1115. int read () {
  1116.  
  1117.        if (nItems < 1) return 0;
  1118.  
  1119.        int value = data[readIndex];
  1120.        readIndex += 1;
  1121.        readIndex %= depth;
  1122.        nItems -= 1;
  1123.  
  1124.        return value;
  1125. }
  1126.  
  1127. /**
  1128.  * returns true if the FIFO is empty
  1129.  */
  1130. boolean empty () {
  1131.  
  1132.        return nItems > 0 ? false : true;
  1133. }
  1134.  
  1135. /**
  1136.  * returns true if the FIFO is half full
  1137.  */
  1138. boolean halfFull () {
  1139.  
  1140.        return nItems > (depth >> 1) ? true : false;
  1141. }
  1142.  
  1143. /**
  1144.  * returns true if the FIFO is full
  1145.  */
  1146. boolean full () {
  1147.  
  1148.        return nItems >= (depth) ? true : false;
  1149. }
  1150.  
  1151. /**
  1152.  * draws the FIFO graphical display
  1153.  * @param g - destination graphics context
  1154.  */
  1155. void paint (Graphics g) {
  1156.  
  1157.        int x, y, w, h;
  1158.  
  1159.        g.setColor (Color.white);
  1160.        g.fillRect (xpos, ypos, width, height);
  1161.        g.setColor (Color.black);
  1162.        g.drawRect (xpos, ypos, width, height);
  1163.  
  1164.        x = writeIndex + xpos + 2;
  1165.        y = ypos - 22;
  1166.        g.drawLine (x, y, x, y + 20);
  1167.        g.drawString ("Write index "+writeIndex, x+2, y+10);
  1168.  
  1169.        x = readIndex + xpos + 2;
  1170.        y = ypos + height + 22;
  1171.        g.drawLine (x, y-20, x, y);
  1172.        g.drawString ("Read index "+readIndex, x+2, y);
  1173.  
  1174.        if (nItems < 1) return;
  1175.  
  1176.        if (nItems > (depth>>1)) g.setColor (Color.red);
  1177.        else g.setColor (Color.green);
  1178.  
  1179.        x = xpos + 2 + readIndex;
  1180.        y = ypos + 2;
  1181.        if (writeIndex > readIndex) w = nItems;
  1182.        else w = width - readIndex - 4;
  1183.        h = height - 4;
  1184.        g.fillRect (x, y, w, h);
  1185.  
  1186.        if (writeIndex > readIndex) return;
  1187.  
  1188.        x = xpos + 2;
  1189.        w = writeIndex;
  1190.        g.fillRect (x, y, w, h);
  1191. }
  1192. }
  1193.  
  1194. /*
  1195.  * a class that generates data continuously
  1196.  */
  1197. class Source extends Thread {
  1198.  
  1199. /*
  1200.  * the FIFO to write into
  1201.  */
  1202. FIFO fifo;
  1203. int value;
  1204.  
  1205. /**
  1206.  * constructor
  1207.  * saves the FIFO instance and starts the thread
  1208.  * @param f - an instance of FIFO
  1209.  */
  1210. public Source (FIFO f) {
  1211.  
  1212.        fifo = f;
  1213.        value = 0;
  1214.  
  1215.        start ();
  1216. }
  1217.  
  1218. /*
  1219.  * the thread that writes one word every 100ms
  1220.  */
  1221. public void run () {
  1222.  
  1223.        while (true) {
  1224.               synchronized (fifo) {
  1225.                      if (fifo.full() == false)
  1226.                             fifo.write (value++);
  1227.               }
  1228.               try {
  1229.                      Thread.sleep (100);
  1230.               } catch (InterruptedException e) {
  1231.               }
  1232.        }
  1233. }
  1234. }
  1235.  
  1236. /*
  1237.  * a class that reads data from the FIFO
  1238.  */
  1239. class Sink extends Thread {
  1240.  
  1241. /*
  1242.  * the FIFO to read from
  1243.  */
  1244. FIFO fifo;
  1245. int value;
  1246.  
  1247. /**
  1248.  * constructor
  1249.  * saves the FIFO instance and starts the thread
  1250.  * @param f - an instance of FIFO
  1251.  */
  1252. public Sink (FIFO f) {
  1253.  
  1254.        fifo = f;
  1255.  
  1256.        start ();
  1257. }
  1258.  
  1259. /*
  1260.  * the thread that reads all data out after the FIFO is half
  1261.  * full
  1262.  */
  1263. public void run () {
  1264.  
  1265.        boolean empty;
  1266.        boolean halfFull;
  1267.  
  1268.        while (true) {
  1269.               synchronized (fifo) {
  1270.                      halfFull = fifo.halfFull ();
  1271.               }
  1272.               if (halfFull) {
  1273.                      try {
  1274.                             Thread.sleep (1000);
  1275.                      } catch (InterruptedException e) {
  1276.                      }
  1277.                      do {
  1278.                             synchronized (fifo) {
  1279.                                    value = fifo.read ();
  1280.                             }
  1281.                             try {
  1282.                                    Thread.sleep (50);
  1283.                             } catch (InterruptedException e) {
  1284.                             }
  1285.                             synchronized (fifo) {
  1286.                                    empty = fifo.empty ();
  1287.                             }
  1288.                      } while (empty == false); 
  1289.               }
  1290.  
  1291.               try {
  1292.                      Thread.sleep (100);
  1293.               } catch (InterruptedException e) {
  1294.               }
  1295.        }
  1296. }
  1297. }
  1298.  
  1299. /*
  1300.  * the applet/application class
  1301.  */
  1302. public class SyncCode extends Applet implements Runnable {
  1303.  
  1304. Source source;
  1305. Sink sink;
  1306. FIFO fifo;
  1307. Thread thread;
  1308.  
  1309. /*
  1310.  * called when the applet is loaded
  1311.  * create instances of FIFO, Source, Sink, and Thread
  1312.  */
  1313. public void init () {
  1314.  
  1315.        fifo = new FIFO (200);
  1316.        source = new Source (fifo);
  1317.        sink = new Sink (fifo);
  1318.  
  1319.        thread = new Thread (this);
  1320. }
  1321.  
  1322. /*
  1323.  * start the graphics update thread
  1324.  */
  1325. public void start () {
  1326.  
  1327.        thread.start ();
  1328. }
  1329.  
  1330.  
  1331. /*
  1332.  * the graphics update thread
  1333.  * call repaint every 100ms
  1334.  */
  1335. public void run () {
  1336.  
  1337.        while (true) {
  1338.               repaint ();
  1339.               try {
  1340.                      Thread.sleep (100);
  1341.               } catch (InterruptedException e) {
  1342.               }
  1343.        }
  1344. }
  1345.  
  1346. /**
  1347.  * called from update() in response to repaint()
  1348.  * @param g - destination graphics context
  1349.  */
  1350. public void paint (Graphics g) {
  1351.  
  1352.        synchronized (fifo) {
  1353.               fifo.paint (g);
  1354.        }
  1355. }
  1356.  
  1357. /**
  1358.  * main() is the application entry point
  1359.  * main() is unused when run as an applet
  1360.  * create a window frame and add the applet inside
  1361.  * @param args[] - command-line arguments
  1362.  */
  1363. public static void main (String args[]) {
  1364.  
  1365.        Frame f = new Frame ("Synchronized code example");
  1366.  
  1367.        SyncCode syncCode = new SyncCode ();
  1368.        f.add ("Center", syncCode);
  1369.        f.setSize (400, 200);
  1370.        f.show ();
  1371.        
  1372.        syncCode.init ();
  1373.        syncCode.start ();
  1374. }
  1375. }
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386. WaitDemo.java:
  1387.  
  1388. import java.awt.*;
  1389. import java.applet.Applet;
  1390.  
  1391. /*
  1392.  * a class for handling first in, first out data structure
  1393.  */
  1394. class FIFO {
  1395.  
  1396. /*
  1397.  * the maximum depth of the FIFO
  1398.  */
  1399. final int MaxDepth = 200;
  1400.  
  1401. /*
  1402.  * the real depth of this FIFO
  1403.  */
  1404. int depth;
  1405.  
  1406. /*
  1407.  * write and read indexes into the data array
  1408.  */
  1409. int writeIndex;
  1410. int readIndex;
  1411.  
  1412. /*
  1413.  * the number of data items currently in the FIFO
  1414.  */
  1415. int nItems;
  1416.  
  1417. /*
  1418.  * the data proper
  1419.  */
  1420. int data[] = new int[MaxDepth];
  1421.  
  1422. /*
  1423.  * width and height of the FIFO graphical display
  1424.  */
  1425. int width;
  1426. int height;
  1427.  
  1428. /*
  1429.  * x and y position of the upper-left corner of the FIFO
  1430.  * graphical display
  1431.  */
  1432. int xpos;
  1433. int ypos;
  1434.  
  1435. /**
  1436.  * the constructor
  1437.  * @param d - depth of the FIFO
  1438.  */
  1439. public FIFO (int d) {
  1440.  
  1441.        depth = d;
  1442.        writeIndex = 0;
  1443.        readIndex = 0;
  1444.        nItems = 0;
  1445.  
  1446.        width = depth + 4;
  1447.        height = 50;
  1448.        xpos = 50;
  1449.        ypos = 75; 
  1450. }
  1451.  
  1452. /**
  1453.  * write one integer value into the FIFO
  1454.  * invoke wait() if the FIFO is full
  1455.  * @param value - the value to write
  1456.  */
  1457. synchronized void write (int value) {
  1458.  
  1459.        if (nItems >= depth) {
  1460.               try {
  1461.                      wait ();
  1462.               } catch (InterruptedException e) {
  1463.               }
  1464.        }
  1465.  
  1466.        data[writeIndex] = value;
  1467.        writeIndex += 1;
  1468.        writeIndex %= depth;
  1469.        nItems += 1;
  1470.        notify ();
  1471. }
  1472.  
  1473. /**
  1474.  * read one integer value from the FIFO
  1475.  * invoke wait() if the FIFO is empty
  1476.  */
  1477. synchronized int read () {
  1478.  
  1479.        if (nItems < 1) {
  1480.               try {
  1481.                      wait ();
  1482.               } catch (InterruptedException e) {
  1483.               }
  1484.        }
  1485.  
  1486.        int value = data[readIndex];
  1487.        readIndex += 1;
  1488.        readIndex %= depth;
  1489.        nItems -= 1;
  1490.        notify ();
  1491.  
  1492.        return value;
  1493. }
  1494.  
  1495. /**
  1496.  * returns true if the FIFO is empty
  1497.  */
  1498. synchronized boolean empty () {
  1499.  
  1500.        return nItems > 0 ? false : true; 
  1501. }
  1502.  
  1503. /**
  1504.  * returns true if the FIFO is half full
  1505.  */
  1506. synchronized boolean halfFull () {
  1507.  
  1508.        return nItems > (depth >> 1) ? true : false;
  1509. }
  1510.  
  1511. /**
  1512.  * returns true if the FIFO is full
  1513.  */
  1514. synchronized boolean full () {
  1515.  
  1516.        return nItems >= (depth) ? true : false; 
  1517. }
  1518.  
  1519. /**
  1520.  * draws the FIFO graphical display
  1521.  * @param g - destination graphics context
  1522.  */
  1523. synchronized void paint (Graphics g) {
  1524.  
  1525.        int x, y, w, h;
  1526.  
  1527.        g.setColor (Color.white);
  1528.        g.fillRect (xpos, ypos, width, height);
  1529.        g.setColor (Color.black);
  1530.        g.drawRect (xpos, ypos, width, height);
  1531.  
  1532.        x = writeIndex + xpos + 2;
  1533.        y = ypos - 22;
  1534.        g.drawLine (x, y, x, y + 20);
  1535.        g.drawString ("Write index "+writeIndex, x+2, y+10);
  1536.  
  1537.        x = readIndex + xpos + 2;
  1538.        y = ypos + height + 22;
  1539.        g.drawLine (x, y-20, x, y);
  1540.        g.drawString ("Read index "+readIndex, x+2, y);
  1541.  
  1542.        if (nItems < 1) return;
  1543.  
  1544.        if (nItems > (depth>>1)) g.setColor (Color.red);
  1545.        else g.setColor (Color.green);
  1546.  
  1547.        x = xpos + 2 + readIndex;
  1548.        y = ypos + 2; 
  1549.        if (writeIndex > readIndex) w = nItems;
  1550.        else w = width - readIndex - 4;
  1551.        h = height - 4;
  1552.        g.fillRect (x, y, w, h);
  1553.  
  1554.        if (writeIndex > readIndex) return;
  1555.  
  1556.        x = xpos + 2;
  1557.        w = writeIndex;
  1558.        g.fillRect (x, y, w, h);
  1559. }
  1560. }
  1561.  
  1562. /*
  1563.  * a class that generates data continuously
  1564.  */
  1565. class Source extends Thread {
  1566.  
  1567. /*
  1568.  * the FIFO to write into
  1569.  */
  1570. FIFO fifo;
  1571. int value;
  1572.  
  1573. /**
  1574.  * constructor
  1575.  * saves the FIFO instance and starts the thread
  1576.  * @param f - an instance of FIFO
  1577.  */
  1578. public Source (FIFO f) {
  1579.  
  1580.        fifo = f;
  1581.        value = 0;
  1582.  
  1583.        start ();
  1584. }
  1585.  
  1586. /*
  1587.  * the thread that writes one word every 50ms on average
  1588.  */
  1589. public void run () {
  1590.  
  1591.        while (true) {
  1592.               if (fifo.full() == false)
  1593.                      fifo.write (value++);
  1594.  
  1595.               try {
  1596.                      Thread.sleep ((int) (100 * Math.random ()));
  1597.               } catch (InterruptedException e) {
  1598.               }
  1599.        }
  1600. }
  1601. }
  1602.  
  1603. /*
  1604.  * a class that reads data from the FIFO
  1605.  */
  1606. class Sink extends Thread {
  1607.  
  1608. /*
  1609.  * the FIFO to read from
  1610.  */
  1611. FIFO fifo;
  1612. int value;
  1613.  
  1614. /**
  1615.  * constructor
  1616.  * saves the FIFO instance and starts the thread
  1617.  * @param f - an instance of FIFO
  1618.  */
  1619. public Sink (FIFO f) {
  1620.  
  1621.        fifo = f;
  1622.  
  1623.        start ();
  1624. }
  1625.  
  1626. /*
  1627.  * the thread that tries to read one word every 50ms on average
  1628.  */
  1629. public void run () {
  1630.  
  1631.        while (true) {
  1632.               value = fifo.read ();
  1633.  
  1634.               try {
  1635.                      Thread.sleep ((int) (100 * Math.random ()));
  1636.               } catch (InterruptedException e) {
  1637.               }
  1638.        }
  1639. }
  1640. }
  1641.  
  1642. /*
  1643.  * the applet/application class
  1644.  */
  1645. public class WaitDemo extends Applet implements Runnable {
  1646.  
  1647. Source source;
  1648. Sink sink;
  1649. FIFO fifo;
  1650. Thread thread;
  1651.  
  1652. /*
  1653.  * called when the applet is loaded
  1654.  * create instances of FIFO, Source, Sink, and Thread
  1655.  */
  1656. public void init () {
  1657.  
  1658.        fifo = new FIFO (200);
  1659.        source = new Source (fifo);
  1660.        sink = new Sink (fifo);
  1661.  
  1662.        thread = new Thread (this);
  1663. }
  1664.  
  1665. /*
  1666.  * start the graphics update thread
  1667.  */
  1668. public void start () {
  1669.  
  1670.        thread.start ();
  1671. }
  1672.  
  1673.  
  1674. /*
  1675.  * the graphics update thread
  1676.  * call repaint every 100ms
  1677.  */
  1678. public void run () {
  1679.  
  1680.        while (true) {
  1681.               repaint ();
  1682.               try {
  1683.                      Thread.sleep (100);
  1684.               } catch (InterruptedException e) {
  1685.               }
  1686.        }
  1687. }
  1688.  
  1689. /**
  1690.  * called from update() in response to repaint()
  1691.  * @param g - destination graphics context
  1692.  */
  1693. public void paint (Graphics g) {
  1694.  
  1695.        fifo.paint (g);
  1696. }
  1697.  
  1698. /**
  1699.  * main() is the application entry point
  1700.  * main() is unused when run as an applet
  1701.  * create a window frame and add the applet inside
  1702.  * @param args[] - command-line arguments
  1703.  */
  1704. public static void main (String args[]) {
  1705.  
  1706.        Frame f = new Frame ("FIFO Demo");
  1707.  
  1708.        WaitDemo waitDemo = new WaitDemo ();
  1709.        f.add ("Center", waitDemo);
  1710.        f.setSize (400, 200);
  1711.        f.show ();
  1712.        
  1713.        waitDemo.init ();
  1714.        waitDemo.start ();
  1715. }
  1716. }
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.