home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / javafile / ch04 / SyncMethod.java < prev    next >
Encoding:
Java Source  |  1998-12-14  |  6.2 KB  |  328 lines

  1. import java.awt.*;
  2. import java.applet.Applet;
  3.  
  4. /*
  5.  * a class for handling first in, first out data structure
  6.  */
  7. class FIFO {
  8.  
  9. /*
  10.  * the maximum depth of the FIFO
  11.  */
  12. final int MaxDepth = 200;
  13.  
  14. /*
  15.  * the real depth of this FIFO
  16.  */
  17. int depth;
  18.  
  19. /*
  20.  * write and read indexes into the data array
  21.  */
  22. int writeIndex;
  23. int readIndex;
  24.  
  25. /*
  26.  * the number of data items currently in the FIFO
  27.  */
  28. int nItems;
  29.  
  30. /*
  31.  * the data proper
  32.  */
  33. int data[] = new int[MaxDepth];
  34.  
  35. /*
  36.  * width and height of the FIFO graphical display
  37.  */
  38. int width;
  39. int height;
  40.  
  41. /*
  42.  * x and y position of the upper-left corner of the FIFO
  43.  * graphical display
  44.  */
  45. int xpos;
  46. int ypos;
  47.  
  48. /**
  49.  * the constructor
  50.  * @param d - depth of the FIFO
  51.  */
  52. public FIFO (int d) {
  53.  
  54.        depth = d;
  55.        writeIndex = 0;
  56.        readIndex = 0;
  57.        nItems = 0;
  58.  
  59.        width = depth + 4;
  60.        height = 50;
  61.        xpos = 50;
  62.        ypos = 75; 
  63. }
  64.  
  65. /**
  66.  * write one integer value into the FIFO
  67.  * @param value - the value to write
  68.  */
  69. synchronized void write (int value) {
  70.  
  71.        if (nItems >= depth) return; 
  72.  
  73.        data[writeIndex] = value;
  74.        writeIndex += 1;
  75.        writeIndex %= depth;
  76.        nItems += 1;
  77. }
  78.  
  79. /**
  80.  * read 1 integer value from the FIFO
  81.  */
  82. synchronized int read () {
  83.  
  84.        if (nItems < 1) return 0;
  85.  
  86.        int value = data[readIndex]; 
  87.        readIndex += 1;
  88.        readIndex %= depth;
  89.        nItems -= 1;
  90.  
  91.        return value;
  92. }
  93.  
  94. /**
  95.  * returns true if the FIFO is empty
  96.  */
  97. synchronized boolean empty () {
  98.  
  99.        return nItems > 0 ? false : true;
  100. }
  101.  
  102. /**
  103.  * returns true if the FIFO is half full
  104.  */
  105. synchronized boolean halfFull () {
  106.  
  107.        return nItems > (depth >> 1) ? true : false;
  108. }
  109.  
  110. /**
  111.  * returns true if the FIFO is full
  112.  */
  113. synchronized boolean full () {
  114.  
  115.        return nItems >= (depth) ? true : false;
  116. }
  117.  
  118. /**
  119.  * draws the FIFO graphical display
  120.  * @param g - destination graphics context
  121.  */
  122. synchronized void paint (Graphics g) {
  123.  
  124.        int x, y, w, h;
  125.  
  126.        g.setColor (Color.white);
  127.        g.fillRect (xpos, ypos, width, height); 
  128.        g.setColor (Color.black);
  129.        g.drawRect (xpos, ypos, width, height);
  130.  
  131.        x = writeIndex + xpos + 2;
  132.        y = ypos - 22;
  133.        g.drawLine (x, y, x, y + 20);
  134.        g.drawString ("Write index "+writeIndex, x+2, y+10);
  135.  
  136.        x = readIndex + xpos + 2;
  137.        y = ypos + height + 22;
  138.        g.drawLine (x, y-20, x, y);
  139.        g.drawString ("Read index "+readIndex, x+2, y);
  140.  
  141.        if (nItems < 1) return;
  142.  
  143.        if (nItems > (depth>>1)) g.setColor (Color.red);
  144.        else g.setColor (Color.green); 
  145.  
  146.        x = xpos + 2 + readIndex;
  147.        y = ypos + 2;
  148.        if (writeIndex > readIndex) w = nItems;
  149.        else w = width - readIndex - 4;
  150.        h = height - 4;
  151.        g.fillRect (x, y, w, h);
  152.  
  153.        if (writeIndex > readIndex) return;
  154.  
  155.        x = xpos + 2;
  156.        w = writeIndex;
  157.        g.fillRect (x, y, w, h); 
  158. }
  159. }
  160.  
  161. /*
  162.  * a class that generates data continuously
  163.  */
  164. class Source extends Thread {
  165.  
  166. /*
  167.  * the FIFO to write into
  168.  */
  169. FIFO fifo;
  170. int value;
  171.  
  172. /**
  173.  * constructor
  174.  * saves the FIFO instance and starts the thread
  175.  * @param f - an instance of FIFO
  176.  */
  177. public Source (FIFO f) {
  178.  
  179.        fifo = f;
  180.        value = 0;
  181.  
  182.        start ();
  183. }
  184.  
  185. /*
  186.  * the thread that writes one word every 100ms
  187.  */
  188. public void run () {
  189.  
  190.        while (true) {
  191.               if (fifo.full() == false)
  192.                      fifo.write (value++);
  193.  
  194.               try {
  195.                      Thread.sleep (100);
  196.               } catch (InterruptedException e) {
  197.               }
  198.        }
  199. }
  200. }
  201.  
  202. /*
  203.  * a class that reads data from the FIFO
  204.  */
  205. class Sink extends Thread {
  206.  
  207. /*
  208.  * the FIFO to read from
  209.  */
  210. FIFO fifo;
  211. int value;
  212.  
  213. /**
  214.  * constructor
  215.  * saves the FIFO instance and starts the thread
  216.  * @param f - an instance of FIFO
  217.  */
  218. public Sink (FIFO f) {
  219.  
  220.        fifo = f;
  221.  
  222.        start ();
  223. }
  224.  
  225. /*
  226.  * the thread that reads all data out after the FIFO is half
  227.  * full
  228.  */
  229. public void run () {
  230.  
  231.        while (true) {
  232.               if (fifo.halfFull()) {
  233.                      try {
  234.                             Thread.sleep (1000);
  235.                      } catch (InterruptedException e) {
  236.                      }
  237.                      while (fifo.empty() == false) {
  238.                             value = fifo.read ();
  239.                             try {
  240.                                    Thread.sleep (50);
  241.                             } catch (InterruptedException e) {
  242.                             }
  243.                      }
  244.               }
  245.  
  246.               try {
  247.                      Thread.sleep (100);
  248.               } catch (InterruptedException e) {
  249.               }
  250.        }
  251. }
  252. }
  253.  
  254. /*
  255.  * the applet/application class
  256.  */
  257. public class SyncMethod extends Applet implements Runnable {
  258.  
  259. Source source;
  260. Sink sink;
  261. FIFO fifo;
  262. Thread thread;
  263.  
  264. /*
  265.  * called when the applet is loaded
  266.  * create instances of FIFO, Source, Sink, and Thread
  267.  */
  268. public void init () {
  269.  
  270.        fifo = new FIFO (200);
  271.        source = new Source (fifo);
  272.        sink = new Sink (fifo);
  273.  
  274.        thread = new Thread (this);
  275. }
  276.  
  277. /*
  278.  * start the graphics update thread
  279.  */
  280. public void start () {
  281.  
  282.        thread.start ();
  283. }
  284.  
  285. /*
  286.  * the graphics update thread
  287.  * call repaint every 100ms
  288.  */
  289. public void run () {
  290.  
  291.        while (true) {
  292.               repaint ();
  293.               try {
  294.                      Thread.sleep (100);
  295.               } catch (InterruptedException e) {
  296.               }
  297.        }
  298. }
  299.  
  300. /**
  301.  * called from update() in response to repaint()
  302.  * @param g - destination graphics context
  303.  */
  304. public void paint (Graphics g) {
  305.  
  306.        fifo.paint (g);
  307. }
  308.  
  309. /**
  310.  * main() is the application entry point
  311.  * main() is unused when run as an applet
  312.  * create a window frame and add the applet inside
  313.  * @param args[] - command-line arguments
  314.  */
  315. public static void main (String args[]) {
  316.  
  317.        Frame f = new Frame ("Synchronized methods example");
  318.  
  319.        SyncMethod syncMethod = new SyncMethod ();
  320.        f.add ("Center", syncMethod);
  321.        f.setSize (400, 200);
  322.        f.show ();
  323.        
  324.        syncMethod.init ();
  325.        syncMethod.start ();
  326. }
  327. }
  328.