Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Concurrency: Java Threads (lectures programs) Sun OnLine Documentations Thread Basics ¾ Example 1: SimpleThread: (Run as 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: Run as 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: interrupting a blocked thread run as 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: Stopping a thread Run as 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: Notifying a blocked thread: Run as 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: Problems with resource sharing while threading: Run as 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 by using the 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: Sharing2mUsing the synchronized keyword in a different place: Run as 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"); } } }