Concurrency: Java Threads

 

(lectures programs)

 

Sun OnLine Documentations

 

 

 

Thread Basics

 

à  Example 1:  SimpleThread:   

ü   (Run  Applet)

 

  public class SimpleThread extends Thread {

 

  private int countDown = 50;

  private static int threadCount = 0;

  private int threadNumber = ++threadCount;

 

  public SimpleThread () {

    System.out.println("Making " + threadNumber);

         }

       

         public void run() {

    while (true) {

      System.out.println("Thread " + threadNumber + "(" + countDown + ")");

       if (--countDown == 0) return;

}

  }

 

  public static void main(String[] args) {

    for(int i = 0; i < 5; i++)

        new SimpleThread().start();

    System.out.println("All Threads Started");

  }

}

 

ü   Example 2: Counter4

ü   (Run   Applet)  

 

public class Counter4 extends JApplet {

 

  private JButton startB = new JButton("Start");

  private Ticker[] s;

 

  class Ticker extends Thread {

    private JButton b = new JButton("Toggle");

    private JTextField t = new JTextField(10);

    private int count = 0;

    private boolean runFlag = true;

 

    public Ticker() {

      b.addActionListener(new ToggleL());

      JPanel p = new JPanel();

      p.add(t);

      p.add(b);

      getContentPane().add(p);

    }

 

    class ToggleL implements ActionListener {

      public void actionPerformed(ActionEvent e) {

        runFlag = !runFlag;

      }

    }

 

    public void run() {

      while (true) {

        if (runFlag) t.setText (Integer.toString(count++));

        try {

               sleep(100);

        } catch(InterruptedException e) {

               System.err.println("Interrupted");

        }

      }

    }

 

  }

 

  class  StartL  implements ActionListener {

    public void actionPerformed(ActionEvent e) {

          startB.setBackground(Color.red);

          startB.setEnabled(false);

          for (int i = 0; i < s.length; i++)

                 s[i].start();

      }

    }

  }

 

 public void init() {

    Container cp = getContentPane();

    cp.setLayout(new FlowLayout());

 

    s = new Ticker[4];

 

    for (int i = 0; i < s.length; i++)

        s[i] = new Ticker();

 

    startB.addActionListener(new StartL());

    cp.add(startB);

  } 

 

   public static void main (String[] args) {

    Counter4 applet = new Counter4 ();

    Console.run (applet, 200, 200);

  }

}

 

You can run this as an application

         % java   Counter4  

 


 

 

Blocking

 

à  Example 1: Interrupt interrupting a blocked thread     

ü   (Run  Applet)  

 

public class Interrupt extends JApplet {

 

  JTextArea  Xout  = new JTextArea(5, 10);

  private JButton interruptB = new JButton("Interrupt");

  private Blocked blockedT = new Blocked();

 

  public void init() {

    Container cp = getContentPane();

    cp.setLayout(new FlowLayout());

    cp.add(interruptB);

    cp.add (new JScrollPane(Xout));

   

    interrupt.addActionListener(

      new ActionListener() {

        public  void actionPerformed(ActionEvent e) {

          interruptB.setBackground(Color.red);

          interruptB.setEnabled(false);

          if (blocked == null) return;

          blockedT.interrupt();

          blocked = null; // to release it

        }

      });

    blockedT.start();

  }

 

  class BlockedT extends Thread {

  

   public synchronized void run() {

     try {

          Xout.append("Thread Started\n");

          wait(); // Blocks

     } catch(InterruptedException e) {

           Xout.append("Thread Interrupted\n");

     }

     Xout.append("Thread Exiting\n");

   }

  }

 

  public static void main (String[] args) {

    Console.run(new Interrupt(), 200, 100);

  }

}

 

 

 

à  Example 2: Stop Stopping a  thread      

ü   (Run Applet)

 

public class Stop extends JApplet {

  JTextArea  Xout  = new JTextArea(5, 15);

  private JButton  stopB = new JButton("Stop");

  private Stopped stoppedT = new Stopped();

 

  public void init () {

    Container cp = getContentPane();

    cp.setLayout(new FlowLayout());

    cp.add(stopB);

    cp.add(new JScrollPane(Xout));

 

    stoppedT.start();

 

    stopB.addActionListener(

      new ActionListener() {

        public  void actionPerformed(ActionEvent e) {

          stopB.setEnabled(false);

          stopB.setBackground(Color.red);

          stoppedT.requestStop();

          stoppedT = null; // to release it

        }

      });

 

      }

 

  class Stopped extends Thread {

   // Must be volatile:

   private volatile boolean stopF = false;

   private int counter = 0;

 

   public synchronized void run() {

    while (!stopF) {

        Xout.append("counter: " + counter++ + "\n");

        try {

           sleep(2000);

        } catch(InterruptedException e) {

            System.err.println("Interrupted");

        }

    }

    if(stopF)

      Xout.append("Detected stop");

   }

  

   public void requestStop() {

      stopF = true;

   }

  }

 

  public static void main (String[] args) {

    Console.run (new Stop(), 200, 100);

  }

}

 

 

 

à  Example 3:  Suspend Notifying a blocked thread:

ü   (Run Applet)

 

public class Suspend extends JApplet {

  private JTextField txt = new JTextField(10);

  private JButton     suspendB = new JButton("Suspend"),

                                 resumeB = new JButton("Resume");

  private Suspendable ssT = new Suspendable();

  private int SuspendCount = 1;

                                          

 

  class Suspendable extends Thread {

    private int count = 0;

    private boolean suspendedF = false;

 

    public Suspendable() {

           start();

    }

    public void funSuspend() {

      suspendedF = true;

    }

 

    public synchronized void funResume() {

      suspendedF = false;

      notify();

    }

   

    public void run() {

      while (true) {

        try {

          sleep(100);

          synchronized (this) {

            while (suspendedF){

                  t.setText("Suspend #: " +  SuspendCount++);

                  wait();

             }

          }

        } catch(InterruptedException e) {

           System.err.println("Interrupted");

        }

        txt.setText(Integer.toString(count++));

      }

    }

  }

 

  public void init() {

    Container cp = getContentPane();

    cp.setLayout(new FlowLayout());

    cp.add(txt);

   

    suspendB.addActionListener(

      new ActionListener() {

        public   void actionPerformed(ActionEvent e) {

          ssT.funSuspend();

          suspendB.setEnabled(false);

          suspendB.setBackground(Color.red);

          resumeB.setEnabled(true);

          resumeB.setBackground(Color.green);

        }

      });

    cp.add (suspendB);

    suspendB.setEnabled(true);

    suspendB.setBackground(Color.green);

 

    resumeB.addActionListener(

      new ActionListener() {

        public  void actionPerformed(ActionEvent e) {

          ssT.funResume();

          suspendB.setEnabled(true);

          suspendB.setBackground(Color.green);

          resumeB.setEnabled(false);

          resumeB.setBackground(Color.red);

        }

      });

    cp.add (resumeB);

    resumeB.setEnabled(false);

    resumeB.setBackground(Color.red);

  }

  }

 

  public static void main (String[] args) {

    Console.run(new Suspend(), 300, 100);

  }

}

 




Sharing

 

à  Example 1: Sharing1: Problems with resource sharing in threading:    

ü   (Run  Applet)

 

 

public class Sharing1 extends JApplet {

  private static int accessCount = 0;

  private static JTextField aCount = new JTextField("0", 7);

 

  public static void incrementAccess() {

    accessCount++;

    aCount.setText(Integer.toString(accessCount));

  }

  private JButton     start = new JButton("Start"),

                             watcher = new JButton("Watch");

  private boolean isApplet = true;

  private int numCounters = 12;

  private int numWatchers = 15;

  private TwoCounter[] s;

 

  class TwoCounter extends Thread {

    private boolean started = false;

    private JTextField        t1 = new JTextField(5),

                                          t2 = new JTextField(5);

    private JLabel l =    new JLabel("count1 == count2");

    private int count1 = 0, count2 = 0;

    // Add the display components as a panel:

    public TwoCounter() {

      JPanel p = new JPanel();

      p.add(t1);

      p.add(t2);

      p.add(l);

      getContentPane().add(p);

    }

    public void start() {

      if(!started) {

        started = true;

        super.start();

      }

    }

public void run() {

      while (true) {

 

        t1.setText(Integer.toString(count1++));

 

        try {

          sleep(5);

        } catch(InterruptedException e) {

          System.err.println("Interrupted");

        }

 

        t2.setText(Integer.toString(count2++));

 

        try {

          sleep(500);

        } catch(InterruptedException e) {

          System.err.println("Interrupted");

        }

      }

}

    public void synchTest() {

      incrementAccess();

      if (count1 != count2)

        l.setText("Unsynched");

    }

  }

  class Watcher extends Thread {

    public Watcher() {

         start();

   }

    public void run() {

      while(true) {

        for (int i = 0; i < s.length; i++)

          s[i].synchTest();

        try {

          sleep(500);

        } catch(InterruptedException e) {

          System.err.println("Interrupted");

        }

      }

    }

  }

  class StartL implements ActionListener {

    public void actionPerformed(ActionEvent e) {

      for(int i = 0; i < s.length; i++)

        s[i].start();

    }

  }

  class WatcherL implements ActionListener {

    public void actionPerformed(ActionEvent e) {

      for(int i = 0; i < numWatchers; i++)

        new Watcher();

    }

  }

  public void init() {

    if (isApplet) {

      String counters = getParameter("size");

      if (counters != null)

        numCounters = Integer.parseInt(counters);

      String watchers = getParameter("watchers");

      if (watchers != null)

        numWatchers = Integer.parseInt(watchers);

    }

    s = new TwoCounter[numCounters];

    Container cp = getContentPane();

    cp.setLayout(new FlowLayout());

    for(int i = 0; i < s.length; i++)

      s[i] = new TwoCounter();

    JPanel p = new JPanel();

    start.addActionListener(new StartL());

    p.add(start);

    watcher.addActionListener(new WatcherL());

    p.add(watcher);

    p.add(new JLabel("Access Count"));

    p.add(aCount);

    cp.add(p);

  }

  public static void main(String[] args) {

    Sharing1 applet = new Sharing1();

    // This isn't an applet, so set the flag and

    // produce the parameter values from args:

    applet.isApplet = false;

    applet.numCounters = (args.length == 0 ? 12 :  Integer.parseInt(args[0]));

    applet.numWatchers = (args.length  <  2 ? 15 : Integer.parseInt(args[1]));

    Console.run(applet, 350,  applet.numCounters * 50);

  }

    }

 

 

 

 

à  Example 2:  Sharing2  Fix  via  synchronized keyword

ü       (Run as Applet)

 

public  synchronized void run() {

     while (true) {

      t1.setText(Integer.toString(count1++));

       try {

          sleep(5);

        } catch(InterruptedException e) {

          System.err.println("Interrupted");

        }

      t2.setText(Integer.toString(count2++));

        try {

          sleep(500);

        } catch(InterruptedException e) {

          System.err.println("Interrupted");

        }

     }

}

 
  

 

 

à  Example 3: Sharing2m using synchronized keyword at different place.

ü      (Run  Applet)

 

public void run() {

      while (true) {

        synchronized(this) { 

       t1.setText(Integer.toString(count1++));

       try {

          sleep(5);

        } catch(InterruptedException e) {

          System.err.println("Interrupted");

        }

       t2.setText(Integer.toString(count2++));

        }

        try {

          sleep(500);

        } catch(InterruptedException e) {

          System.err.println("Interrupted");

        }

      }

}