Presentation is loading. Please wait.

Presentation is loading. Please wait.

95-712 OOP/Java1 Introductory Java Threads GUI examples taken from “Computing Concepts with Java 2” by Cay Horstmann Thread examples taken from “The Java.

Similar presentations


Presentation on theme: "95-712 OOP/Java1 Introductory Java Threads GUI examples taken from “Computing Concepts with Java 2” by Cay Horstmann Thread examples taken from “The Java."— Presentation transcript:

1 95-712 OOP/Java1 Introductory Java Threads GUI examples taken from “Computing Concepts with Java 2” by Cay Horstmann Thread examples taken from “The Java Programming Language” By Arnold and Gosling and from Cay Horstmann’s “Core Java 2 Advanced” Producer/Consumer example from Eckel “Thinking in Java”

2 95-712 OOP/Java2 Java Threads Four kinds of thread programming Examples: –A GUI application –A server application –Producer/Consumer and Mutual Exclusion

3 95-712 OOP/Java3 Four Kinds of Thread Programming 1) Unrelated Threads 2) Related but Unsynchronized Threads 3) Mutually-Exclusive Threads 4) Communicating Mutually-Exclusive Threads

4 95-712 OOP/Java4 class Coffee extends Thread { Coffee(String name) { super(name); } public void run() { for(int n = 1; n <= 3; n++) { System.out.println("I like coffee"); yield(); System.out.println(this.getName()); yield(); } Unrelated Threads

5 95-712 OOP/Java5 class Tea extends Thread { Tea(String name) { super(name); } public void run() { for(int n = 1; n <= 3; n++) { System.out.println("I like tea"); yield(); System.out.println(this.getName()); yield(); }

6 95-712 OOP/Java6 public class Drinks { public static void main(String args[]) { System.out.println("I am main"); Coffee t1 = new Coffee("Wawa Coffee"); Tea t2 = new Tea(“Sleepy Time Tea"); t1.start(); t2.start(); System.out.println("Main is done"); }

7 95-712 OOP/Java7 I am main Main is done I like coffee I like tea Wawa Coffee Sleepy Time Tea I like coffee I like tea Wawa Coffee Sleepy Time Tea I like coffee I like tea Wawa Coffee Sleepy Time Tea Output Main finishes right away Threads are sharing time This program has three threads.

8 95-712 OOP/Java8 Using sleep() in unrelated threads The call sleep(millis) puts the currently executing thread to sleep for at least the specified number of milliseconds. "At least“ means there is no guarantee the thread will wake up in exactly the specified time. Other thread scheduling can interfere. Unrelated Threads Part II

9 95-712 OOP/Java9 class Coffee extends Thread { Coffee(String name) { super(name); } public void run() { for(int n = 1; n <= 3; n++) { System.out.println("I like coffee"); try { sleep(1000); // 1 second } catch(InterruptedException e) {} System.out.println(this.getName()); }

10 95-712 OOP/Java10 class Tea extends Thread { Tea(String name) { super(name); } public void run() { for(int n = 1; n <= 5; n++) { System.out.println("I like tea"); System.out.println(getName()); }

11 95-712 OOP/Java11 public class Drinks2 { public static void main(String args[]) { System.out.println("I am main"); Coffee t1 = new Coffee("Wawa Coffee"); Tea t2 = new Tea("China Tea"); t1.start(); t2.start(); System.out.println("Main is done"); }

12 95-712 OOP/Java12 I am main Main is done I like coffee I like tea China Tea I like tea China Tea I like tea China Tea I like tea China Tea I like tea China Tea Wawa Coffee I like coffee Wawa Coffee I like coffee Wawa Coffee 1 second pausing after each “I like coffee” After “I like coffee”, the coffee thread goes to sleep and the tea thread gets to finish and die.

13 95-712 OOP/Java13 Yield() and Sleep() Yield() may have no effect on some implementations. The thread scheduler might make no effort toward fairness. The yielding thread may be picked again even though other threads want a turn. It is a good idea to call sleep() instead.

14 95-712 OOP/Java14 An Example Without Threads Black ball bounces for awhile and then stops. If you then click start, a new ball bounces for awhile and then stops. Close only works between balls. If the ball is moving and you click close, the close message is queued.

15 95-712 OOP/Java15 // From Cay Horstmann Core Java 2 Advanced import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Bounce { public static void main(String[] args) { JFrame frame = new BounceFrame(); frame.show(); }

16 95-712 OOP/Java16 class BounceFrame extends JFrame { public BounceFrame() { setSize(300, 200); setTitle("Bounce"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } );

17 95-712 OOP/Java17 Container contentPane = getContentPane(); canvas = new JPanel(); contentPane.add(canvas, "Center"); JPanel p = new JPanel(); addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { Ball b = new Ball(canvas); b.bounce(); } });

18 95-712 OOP/Java18 addButton(p, "Close", new ActionListener() { public void actionPerformed(ActionEvent evt) { System.exit(0); } }); contentPane.add(p, "South"); } public void addButton(Container c, String title, ActionListener a) { JButton b = new JButton(title); c.add(b); b.addActionListener(a); } private JPanel canvas; }

19 95-712 OOP/Java19 class Ball { public Ball(JPanel b) { box = b; } public void draw() { Graphics g = box.getGraphics(); g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); }

20 95-712 OOP/Java20 public void move() { Graphics g = box.getGraphics(); g.setXORMode(box.getBackground()); g.fillOval(x, y, XSIZE, YSIZE); x += dx; y += dy; Dimension d = box.getSize(); if (x < 0) { x = 0; dx = -dx; } if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; } if (y < 0) { y = 0; dy = -dy; } if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; } g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); }

21 95-712 OOP/Java21 public void bounce() { draw(); for (int i = 1; i <= 1000; i++) { move(); try { Thread.sleep(5); } catch(InterruptedException e) {} } private JPanel box; private static final int XSIZE = 10; private static final int YSIZE = 10; private int x = 0; private int y = 0; private int dx = 2; private int dy = 2; }

22 95-712 OOP/Java22 Bouncing With Threads The close button works in an instant. Each time the start button is clicked a new ball appears. The screen above shows four fast moving bouncing balls.

23 95-712 OOP/Java23 addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { Ball b = new Ball(canvas); b.start(); } }); We use start() rather than bounce() on the ball object…

24 95-712 OOP/Java24 …and have the Ball class extend Thread and implement run() rather than bounce(). class Ball extends Thread : public void run() { try { draw(); for (int i = 1; i <= 1000; i++) { move(); sleep(5); } catch(InterruptedException e) {} }

25 95-712 OOP/Java25 Ping Pong Adapted from "The Java Programming Language", Arnold and Gosling After a thread is created, you can configure it – set its name, its initial priority, and so on. The start() method spawns a new thread of control based on the data in the thread object and then returns. Now, the Java virtual machine invokes the new thread's run method, making the thread active. When a thread's run method returns, the thread has exited. The thread may be manipulated with a number of methods, including the interrupt() method as shown in this example.

26 95-712 OOP/Java26 public class PingPong extends Thread { private String word; private int delay; public PingPong(String whatToSay, int delayTime) { word = whatToSay; delay = delayTime; }

27 95-712 OOP/Java27 public void run() { try { for(;;) { System.out.println(word+" "); sleep(delay); } catch (InterruptedException e) { System.out.println("Interrupted!!!!!"); return; }

28 95-712 OOP/Java28 public static void main(String args[]) { PingPong t1 = new PingPong("\tping",33); t1.start(); PingPong t2 = new PingPong("Pong",100); t2.start(); try { Thread.sleep(5000); } catch(InterruptedException e) { // will not be printed System.out.println("Good morning"); return; }

29 95-712 OOP/Java29 Thread myThread = Thread.currentThread(); for (int t = 1 ; t <= 10; t++) System.out.println("In Main..." + myThread.getName()); t1.interrupt(); }

30 95-712 OOP/Java30 C:\McCarthy\threads\PingPong>java PingPong ping Pong ping Pong ping Pong ping : Main is asleep. For 5 seconds ping and pong take turns sleeping and running

31 95-712 OOP/Java31 Pong ping Pong In Main...main Interrupted!!!!! Pong : “Pongs” forever or until until ctrl-c Main wakes up Main interrupts Ping and ping dies.

32 95-712 OOP/Java32 A Thread Application --A Simple Web Server Responds by sending the same file on each hit Creates a new thread on each hit

33 95-712 OOP/Java33 // A simple web server // Responds with the same file on each hit import java.net.*; import java.io.*; import java.util.*; public class OneFile extends Thread { static String theData = ""; static String contentType; static int contentLength; Socket theConnection;

34 95-712 OOP/Java34 // construct each OneFile object with an existing socket public OneFile(Socket s) { theConnection = s; } // run the following code on each object public void run() { try { // get a PrintStream attached to this socket PrintStream os = new PrintStream( theConnection.getOutputStream()); // get a DataInputStream attached to this socket DataInputStream is = new DataInputStream( theConnection.getInputStream()); // read a line from the socket String request = is.readLine();

35 95-712 OOP/Java35 // HTTP/1.0 and later send a MIME header if(request.indexOf("HTTP/") != -1) { // we need to read the rest of the MIME header while(true) { String thisLine = is.readLine(); if(thisLine.trim().equals("")) break; } // respond to the client os.print("HTTP/1.0 200 OK\r\n"); // send the date Date now = new Date(); os.print("Date: " + now + "\r\n"); // send our name os.print("Server: OneFile 1.0\r\n");

36 95-712 OOP/Java36 // send the contentLength os.print("Content-length: " + contentLength + "\r\n"); // send the content type os.print("Content-type: " + contentType + "\r\n\r\n"); } // send the file in the string os.println(theData); theConnection.close(); } catch(IOException e) { }

37 95-712 OOP/Java37 // main loads the file and creates the object on every hit public static void main(String args[] ) { int thePort; ServerSocket ss; Socket theConnection; FileInputStream theFile; // cache the file try { // open file and create a DataInputStream theFile = new FileInputStream(args[0]); DataInputStream dis = new DataInputStream(theFile);

38 95-712 OOP/Java38 // determine the content type of this file if(args[0].endsWith(".html") || args[0].endsWith(".htm") ) { contentType = "text/html"; } else { contentType = "text/plain"; } // read the file into the string theData try { String thisLine; while((thisLine = dis.readLine()) != null) { theData += thisLine + "\n"; } catch(Exception e) { System.err.println("Error " + e); }

39 95-712 OOP/Java39 catch(Exception e) { System.err.println(e); System.err.println("usage: java onefile filename port"); System.exit(1); } // set the port to listen on try { thePort = Integer.parseInt(args[1]); if(thePort 65535) thePort = 80; } catch(Exception e) { thePort = 80; }

40 95-712 OOP/Java40 // create a server socket try { ss = new ServerSocket(thePort); System.out.println("Accepting connections on port " + ss.getLocalPort()); System.out.println("Data to be sent:"); System.out.println(theData); while(true) { // stop and wait for a connection Socket socketTemp = ss.accept(); // we have a socket so create a handler OneFile fs = new OneFile(socketTemp); // start the handler running fs.start(); } catch(IOException e) {System.out.println("Socket error"); } }

41 95-712 OOP/Java41 Mutually-Exclusive Threads Single-threaded programs are lonely. We only need to think about one entity moving about doing one thing at a time. With concurrency, things aren’t lonely anymore. Entities may collide and interfere with each other.

42 95-712 OOP/Java42 Eckel’s IntGenerator public abstract class IntGenerator { private boolean canceled = false; // derived classes say how they compute next public abstract int next(); public void cancel() { canceled = true; } public boolean isCanceled() { return canceled; } If another concrete class extends this class then it must implement the next method.

43 95-712 OOP/Java43 Eckel’s EvenGenerator public class EvenGenerator extends IntGenerator { private int currentEvenValue = 0; public int next() { ++currentEvenValue; return currentEvenValue; } public static void main(String args[]) { EvenChecker.test(new EvenGenerator()); } An EvenGenerator object generates integers. But we will have trouble here.

44 95-712 OOP/Java44 Eckel’s EvenChecker (1) import java.util.concurrent.*; public class EvenChecker implements Runnable { private IntGenerator generator; private final int id; public EvenChecker(IntGenerator g, int ident) { generator = g; id = ident; }

45 95-712 OOP/Java45 Eckel’s EvenChecker (2) public void run() { while(!generator.isCanceled()) { int val = generator.next(); if(val % 2 != 0) { System.out.println(val + "not even"); generator.cancel(); }

46 95-712 OOP/Java46 Eckel’s EvenChecker (3) public static void test(IntGenerator gp, int count) { System.out.println("Control-C to exit"); ExecutorService exec = Executors.newCachedThreadPool(); for(int i = 0; i < count; i++) { exec.execute(new EvenChecker(gp,i)); } exec.shutdown(); } public static void test(IntGenerator gp) { test(gp,10); }

47 95-712 OOP/Java47 Output java EvenGenerator Control-C to exit 25907not even 25909not even 25911not even Why did we exit? What went wrong? What does Eckel suggest we do?

48 95-712 OOP/Java48 Much better!! public class EvenGenerator extends IntGenerator { private int currentEvenValue = 0; synchronized public int next() { ++currentEvenValue; // Danger point here! ++currentEvenValue; if(currentEvenValue < 0) System.out.println("We went below 0"); System.out.println(currentEvenValue); return currentEvenValue; } public static void main(String[] args) { EvenChecker.test(new EvenGenerator()); } Even a single increment is not an atomic operation. Eckel, page 1156

49 95-712 OOP/Java49 Synchronization (1) To solve the problem of thread collision, concurrency schemes serialize access to shared resources. This means that only one task at a time may access the shared resource. The synchronized key word produces mutual exclusion. Before executing the shared, synchronized code, a task checks to see if a lock is available, acquires it, executes the code and releases the lock. If a task is in a call to one of the synchronized methods, all other tasks are blocked from entering any of the synchronized methods of that object until the first task returns from its call. Eckel, page 1154

50 95-712 OOP/Java50 Synchronization (2) All objects automatically contain a single lock (also referred to as a monitor). Instance members accessed from synchronized code should be private to prevent access to them from outside the method. A task may acquire more than one lock on the same object. Suppose we call synchronized foo() and foo() calls synchornized foo2(). We have two locks on the object. There is also a single lock per class for static methods. Eckel, page 1155

51 95-712 OOP/Java51 Brian’s Rule of Synchronization “If you are writing a variable that might next be read by another thread, or reading a variable that might have last been written by another thread, you must use synchronization, and further, bothe the reader and the writer must synchronize using the same monitor lock.” Eckel, page 1156 From Brian Goetz, author of “Java Concurrency in Practice”

52 95-712 OOP/Java52 Communicating Mutually-Exclusive Threads OK, so we are not interfering. But now we need to cooperate. In some activities, one part of a problem must be solved before beginning the next part. We don’t want to “busy wait” pooling for a state change. So, our thread calls wait(). We wait until another thread calls notify(). A call on wait() suspends execution and releases the lock. It’s executed from within a synchronized method. A call on notify() must also be done within a synchronized method.

53 95-712 OOP/Java53 Eckel’s WaxOMatic // WaxOMatic.java // Basic task cooperation. import java.util.concurrent.*; class Car { private boolean waxOn = false; public synchronized void waxed() { waxOn = true; // Ready to buff notifyAll(); } public synchronized void buffed() { waxOn = false; // Ready for another coat of wax notifyAll(); }

54 95-712 OOP/Java54 public synchronized void waitForWaxing() throws InterruptedException { while(waxOn == false) wait(); } public synchronized void waitForBuffing() throws InterruptedException { while(waxOn == true) wait(); }

55 95-712 OOP/Java55 class WaxOn implements Runnable { private Car car; public WaxOn(Car c) { car = c; } public void run() { try { while(!Thread.interrupted()) { System.out.println("Wax On! "); TimeUnit.MILLISECONDS.sleep(200); car.waxed(); car.waitForBuffing(); } } catch(InterruptedException e) { System.out.println("Exiting via interrupt"); } System.out.println("Ending Wax On task"); }

56 95-712 OOP/Java56 class WaxOff implements Runnable { private Car car; public WaxOff(Car c) { car = c; } public void run() { try { while(!Thread.interrupted()) { car.waitForWaxing(); System.out.println("Wax Off! "); TimeUnit.MILLISECONDS.sleep(200); car.buffed(); } } catch(InterruptedException e) { System.out.println("Exiting via interrupt"); } System.out.println("Ending Wax Off task"); }

57 95-712 OOP/Java57 public class WaxOMatic { public static void main(String[] args) throws Exception { Car car = new Car(); ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new WaxOff(car)); exec.execute(new WaxOn(car)); TimeUnit.SECONDS.sleep(5); // Run for a while... exec.shutdownNow(); // Interrupt all tasks }

58 95-712 OOP/Java58 Output Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! : Exiting via interrupt Ending Wax Off task Exiting via interrupt Ending Wax On task


Download ppt "95-712 OOP/Java1 Introductory Java Threads GUI examples taken from “Computing Concepts with Java 2” by Cay Horstmann Thread examples taken from “The Java."

Similar presentations


Ads by Google