1 / 28

Defining threads in Java

Learn about defining threads in Java for distributed software engineering, including the use of inheritance and composition. Understand the execution sequence of statements and how to start a new thread of execution.

rday
Download Presentation

Defining threads in Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Defining threads in Java Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  2. Thread definition • Two ways: • Using inheritance: Extend the class java.lang.Thread • Using composition: Define a class that implements the Runnable interface • Simplest way is 1, but as you may know well, composition is a much more flexible way. • Read: javadoc for the class java.lang.Thread Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  3. Thread definition: Using inheritance public class MyThreadClass extends Thread { // … } • The class myThreadClass must overwrite the method public void run(); • This method is the equivalent “main()” for any thread different to the main thread. • The thread sequence of statements being executed include: • Every statement executed by the thread is in this run() method or • Any other statement from any other method invoked from run(). • No other method in the class containing run() is expected to be executed in the thread, unless called by run() directly or indirectly. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  4. public class MyThreadClass extends Thread { // … public void run(){ // This method and the methods it // calls are the only ones that run // on this thread. } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  5. Spawning threads • New threads are spawned from threads already running. • For example from the main() thread. • To create a thread: • Make an instance of the thread class defined. • Flag the start of execution of the run() method in the thread instance by invoking the start() method on it. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  6. Starting a new thread of execution MyThreadClass mt = new MyThreadClass(); mt.start(); • A call to the start() method returns right away. • It does not wait for the thread to start. Thread is scheduled to start execution. • The thread used to create and start mt is free to continue execution of its own sequence of statements, right after invoking start() • Cannot assume that mt will start right away. • The parent thread to mt signals JVM that mt should be started as soon as convenient for the thread scheduler. • At some unpredictable time in very near future, mt will come alive and invokes the run() method. • Important: the invocation of the start() method is asynchronous with the thread that makes such call. It’s only purpose is to have the thread scheduled for execution. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  7. Actual execution of two threads • Two threads can run: • Concurrently and independently • Or • In parallel, where each sequence of statements is executed at the very same instance. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  8. Threads are not objects • The superclass java.lang.Thread is NOT a thread, it is a thread controller. • When you define subclasses of Thread you are NOT defining an object. You are specifying an execution sequence in the run method to be executed by an instance of the thread being defined. • If defining subclass of Thread contains a method not called in run(), that method will not be expected to execute in that Thread being defined. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  9. Examples public class TwoThread extends Thread { public void run() { for ( int i = 0; i < 10; i++ ) { System.out.println("New thread"); } } public static void main(String[] args) { TwoThread tt = new TwoThread2(); tt.start(); for ( int i = 0; i < 10; i++ ) { System.out.println("Main thread"); } } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  10. Examples public class TwoThread extends Thread { public void run() { for ( int i = 0; i < 10; i++ ) { System.out.println("New thread"); try { Thread.sleep(100); }catch (InterruptedException e) { } } } public static void main(String[] args) { TwoThread tt = new TwoThread(); tt.start(); for ( int i = 0; i < 10; i++ ) { System.out.println("Main thread"); } } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  11. Examples public class TwoThread extends Thread { private Thread creatorThread; public TwoThread() { // make a note of thread that constructed me! creatorThread = Thread.currentThread(); } public void run() { for ( int i = 0; i < 10; i++ ) {printMsg();} } public void printMsg() { // get a reference to the thread running this Thread t = Thread.currentThread(); if ( t == creatorThread ) { System.out.println("Creator thread"); } else if ( t == this ) { System.out.println("New thread"); } else { System.out.println("Mystery thread”); } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  12. Examples public static void main(String[] args) { TwoThread tt = new TwoThread(); tt.start(); for ( int i = 0; i < 10; i++ ) { tt.printMsg(); } } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  13. Thread constructors Thread() Allocates a new Thread object. Thread(String name) Allocates a new Thread object. Thread(Runnable target) Allocates a new Thread object. Thread(Runnable target, String name) Allocates a new Thread object. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  14. Thread constructors Thread(ThreadGroup group, String name) Allocates a new Thread object. Thread(ThreadGroup group, Runnable target) Allocates a new Thread object. Thread(ThreadGroup group, Runnable target, String name) Allocates a new Thread object so that it has target as its run object, has the specified name as its name, and belongs to the thread group referred to by group. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  15. Thread class API • Thread.currentThread() • Thread.sleep() • getName() • setName() Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  16. Defining threads via composition: Implementing Runnable interface Runnable { public void run(); } • Use this interface to define a class that is designed to provide the sequence to be executed by a thread. The class implements Runnable. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  17. Defining threads via composition: Implementing Runnable • Having defined a class A that implements the Runnable interface, to create a thread object use the second type of constructors of the Thread class A a = new A(); Thread mt = new Thread(a); mt.start(); Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  18. Problem specs • Write a timer with a graphical interface. • Analysis: • Timer model • Knows: current time • Does: start, stop • But: any time after an instance of the timer is sent the command start, you should be able to stop it. • How to do it?? CANNOT do it using sequential programming. • Model the Timer such that in one thread it keeps counting, and with another it can be stopped. • Thus: the counting must know if the timer was stop at which time it quits counting. • First a Solution: • Provided by a book author who will remain anonymous. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  19. JComponent SecondCounter UML of Solution The structure of this solution tells us that SecondCounter is modeling the timer as a subclass of Jcomponent. Thus: we cannot subclass it from Thread! Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  20. Runnable JComponent SecondCounter Solution Using composition Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  21. import java.awt.*; import javax.swing.*; import java.text.*; public class SecondCounterRunnable2 extends JComponent implements Runnable {public SecondCounterRunnable2() { paintFont = new Font("SansSerif", Font.BOLD, 14); timeMsg = "never started"; arcLen = 0;}public void run() { runClock();} Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  22. public void runClock() { DecimalFormat fmt = new DecimalFormat("0.000"); long normalSleepTime = 100; int counter = 0; keepRunning = true; while ( keepRunning ) { try { Thread.sleep(normalSleepTime); } catch ( InterruptedException x ) { // ignore } counter++; double counterSecs = counter / 10.0; timeMsg = fmt.format(counterSecs); arcLen = (((int)counterSecs) % 60 ) * 360 / 60; repaint(); } } public void stopClock() { keepRunning = false; } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  23. SecondCounter Logic • The method runClock specifies and implements the start method for a timer. • It keeps track of time with a loop, where in each iteration it sleeps 100 miliseconds (ie 1/10 of a second.). • It keeps track of the number of times it sleeps for that amount. And every time it sleeps of that amount it updates the length of the arcLength is supposed to be drawn on the display. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  24. public void paint(Graphics g) { g.setColor(Color.black); g.setFont(paintFont); g.drawString(timeMsg, 0, 15); g.fillOval(0, 20, 100, 100); // black border g.setColor(Color.white); g.fillOval(3, 23, 94, 94); // white for unused portion g.setColor(Color.blue); // blue for used portion g.fillArc(2, 22, 96, 96, 90, -arcLen);}private boolean keepRunning;private Font paintFont;private String timeMsg;private int arcLen; }//end SecondCounterRunnable2 Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  25. import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.border.*;public class SecondCounterRunnableMain2 extends JPanel { public SecondCounterRunnableMain2() { sc = new SecondCounterRunnable2(); startB = new JButton("Start"); stopB = new JButton("Stop"); stopB.setEnabled(false); // begin with this disabled startB.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // disable to stop more "start" requests startB.setEnabled(false); // Create and start a new thread to run the counterThread counterThread = new Thread(sc, "SecondCounter"); counterThread.start(); stopB.setEnabled(true); stopB.requestFocus(); }}); Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  26. stopB.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { stopB.setEnabled(false); sc.stopClock(); startB.setEnabled(true); startB.requestFocus();}}); JPanel innerButtonP = new JPanel(); innerButtonP.setLayout(new GridLayout(0, 1, 0, 3)); innerButtonP.add(startB); innerButtonP.add(stopB); JPanel buttonP = new JPanel(); buttonP.setLayout(new BorderLayout()); buttonP.add(innerButtonP, BorderLayout.NORTH); this.setLayout(new BorderLayout(10, 10)); this.setBorder(new EmptyBorder(20, 20, 20, 20)); this.add(buttonP, BorderLayout.WEST); this.add(sc, BorderLayout.CENTER); } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  27. public static void main(String[] args) { SecondCounterRunnableMain2 scm = new SecondCounterRunnableMain2(); JFrame f = new JFrame("Second Counter Runnable"); f.setContentPane(scm); f.setSize(320, 200); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }});} private SecondCounterRunnable2 sc;private JButton startB;private JButton stopB; }//end SecondCounterRunnableMain2 Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

  28. SecondCounter inaccuracy • Notice that after sleeping for 100 milliseconds, it performs some computations to find the arcLength to draw. • These computations take some minimum time • BUT: over time (after some hundreds of seconds) the display will not be correct. • How to fix problem: • Have an absolute clock and use it to measure elapsed time as well. • When finishing computations in the loop, compare time based on the loop with the time using the absolute clock and adjust when need be. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads

More Related