Fachbereich Informatik und Elektrotechnik Java Threads Java Threads Concurrent Programming Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Concurrency versus Parallelism Concurrency Parallelism Time Time Task 2 Task 2 Task 1 Task 1 Single-CPU system Programming in Java, Helmut Dispert Requires a multiple-CPU system Fachbereich Informatik und Elektrotechnik Java Thread Definition Synonyms: • Lightweight Process • Execution Context Definition: • A thread is a single sequential flow of control within a program. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Threads One Thread A Program Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Threads Two Threads A Program Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Threads and Parallelism Threads enable parallelism within a program process. Each thread may take a different path of code execution through a program. • Single processor machines simulate simultaneous execution by running each thread for a very short time, then performing a context switch to another thread. • Threads make use of multiple processor machines (with two or more CPUs on a board). Each thread has it own resource overhead of local variables and program counters. Ref.: http://www.wilsonmar.com Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Threads Operating System Process 1 Process 2 Process 3 (Virtual Java Machine) Storage Thread 1 Local Variables 1 Thread 2 Local Variables 2 Thread 3 Local Variables 3 Multithreaded Processes in a multithreaded environment Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Threads Thread 1 Program Counter Stack Segment Thread 2 Program Counter Stack Segment 4 Data Segment Code Segment Files Task - Process Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Implicit Threads Creating implicit threads with AWT, Swing: Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Implicit Threads //AwtThread.java - doing two things at once import java.awt.*; thread executing import java.awt.event.*; main() import javax.swing.*; class AwtThread { public static void main(String[] args) throws InterruptedException { createGUI(); int count = 0; while (true) { count++; // go to sleep for 1 second = 1000 milliseconds Thread.currentThread().sleep(1000); System.out.println("count is now " + count); System.out.flush(); // force output to print now } } continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Implicit Threads static void createGUI() { JFrame frame = new JFrame("AwtThread"); Container pane = frame.getContentPane(); JButton quit = new JButton("Quit"); quit.addActionListener(new GoodBye()); pane.add(quit, BorderLayout.NORTH); JButton counter = new JButton("Click to count"); counter.addActionListener(new ClickCounter()); pane.add(counter, BorderLayout.SOUTH); frame.pack(); frame.show(); } } thread reading GUI events continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Implicit Threads //ClickCounter.java - count button clicks class ClickCounter implements ActionListener { public void actionPerformed(ActionEvent e) { count++; System.out.println("Total clicks is " + count); } int count = 0; } class GoodBye implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Goodbye!"); System.exit(0); } } Ref.: Ira Pohl, Charlie McDowell, Java by Dissection Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Implicit Threads - AWT thread executing main() thread reading GUI events Java Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Definition Thread Attributes: • Thread Body: method run () • Thread State: state diagram (running, sleeping, dead) • Thread Priority: information for Java scheduler • Daemon Threads: service for other threads • Thread Group: group of related threads Daemon Threads: Daemon threads are threads that work in the background to support the runtime environment, they are service providers for other threads running in the same process. Any Java thread can be a daemon thread. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Implementation Thread Implementation: • Way 1: Extend class Thread: class ClassName extends Thread Extended class must implement method run() public void run() • Way 2: Implementation of interface Runnable public class ClassName extends SuperClass implements Runnable Rule of Thumb: If a class must subclass some other class (the most common example being Applet), Runnable has to be used as described in option 2. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Implementation Erweitern der Klasse Thread oder Implementieren von Runnable? Vorteil Nachteil Ableiten von Thread (extends Thread) Programmcode in run() kann die Methoden der Klasse Thread nutzen Da es in Java keine Mehrfachvererbung gibt, kann die Klasse nur Thread erweitern Implementieren von Runnable (implements Runnable) Die Klasse kann von einer anderen, problemspezifischen Klasse erben Kann sich nur mit Umwegen selbst starten. Allgemein: Thread – Methoden können nur über Umwege genutzt werden. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Implementation Methods of class Thread that can be called: void start() void stop() void sleep (long wait_time) throws InterruptedException void suspend() void resume() void join(long wait_time) throws InterruptedException boolean isAlive() Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Implementation Java.lang.Thread Class Methods (native Java v1.3+) Method Return Type Description currentThread Thread Returns an object reference to the thread in which it is invoked. getName String Retrieve the name of the thread object or instance. getPriority int Retrieve the thread instance's priority. isAlive boolean Determine if the thread is currently running. run void This method is the entry point for threads, like the main method for applications. start void Start the thread by calling its run method. sleep void Suspend a thread for a specified amount of time (in milliseconds). wait void moves an object into a waiting state where it waits for a lock to be released. notify void Remove a thread from the waiting state and place it in the ready-to-run state. The wait(), notify(), and notifyAll() methods for synchronized thread control Ref.: in Java 1.2+ are part of the Object class. http://www.wilsonmar.com Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Methods Java Thread Methods void start() Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread. void stop() Deprecated. This method is inherently unsafe. void suspend() Deprecated. This method has been deprecated, as it is inherently deadlock-prone. void resume() Deprecated. This method exists solely for use with suspend(), which has been deprecated. continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Methods Java Thread Methods void join() Waits for this thread to die. void join(long millis) Waits at most millis milliseconds for this thread to die. void join(long millis, int nanos) Waits at most millis milliseconds plus nanos nanoseconds for this thread to die. boolean isAlive() Tests if this thread is alive. getName() Returns this thread's name. getPriority() Returns this thread's priority. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Threads: Constructor Summary Thread() Allocates a new Thread object. Thread() Thread(Runnable target) Thread(Runnable target, String name) Thread(String name) Docu Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Life Cycle (State Diagram) Thread States according to Java 1.2 yield() new Thread() New Thread start() Runnable Not Runnable stop() or run() exits stop() stop() Dead Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Life Cycle (State Diagram) Thread States according to Java 1.2 New When a Thread is created it is into the New state. A New State Thread is not running. Running (Runnable) A call to the Thread method start() is required to move the Thread from the New State to the Runnable State. A Thread in the Runnable State is eligible to execute on the CPU. A Runnable State Thread will move on and off the CPU due to scheduling assignments. Dead A Thread moves from Runnable State to Dead State when the run() method exits or the Thread stop() method is called. Note that a Thread that has stopped is dead, not suspended. Blocked (Not Runnable) The last Thread state is Blocked State. The Blocked State contains the Threads that can not execute due to a wait(), suspend(), sleep(), or I/O wait. When the reason for the block is removed, the Thread moves back to the Runnable State. Thread methods suspend( ), resume( ), and stop( ) were deprecated by Java v1.3. Ref.: http://www.wilsonmar.com Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Life Cycle (State Diagram) Thread States according to Java 1.3 Object.notify(); Object.notifyAll() Ready-to-run Sleeping start() chosen by scheduler Waiting Thread.sleep() Object.wait() scheduler swap or Thread.yield() done Dead (finished) Running (executing) data/sync received another thread closes socket Blocked on I/O or Sync Ref.: http://www.wilsonmar.com Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Life Cycle (State Diagram) Thread States according to Java 1.3 • Ready-to-run waiting for its turn to be picked for execution by the thread scheduler based on thread priorities. • Running (IsAlive) The thread's code is being actively executed by a processor and will run until it is swapped out, becomes blocked, or voluntarily give up its turn with a yield method which generally, because of context switching overhead, should not be used more than about five times per second • Waiting A Thread is in a blocked state while it waits for some external processing (such as file I/O) to finish. • Sleeping Threads are forcibly put to sleep (suspended) by a thread.sleep() java call. • Blocked on I/O Will move to Ready-to-Run after I/O condition changes (reading a byte of data). • Blocked on Sync Will move to Ready-to-Run when a lock is acquired (passes synchronized statement). • Dead (Terminated) The thread has finished working and cannot be resumed. Ref.: http://www.wilsonmar.com Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Example Implement method run() public void run() { // Code that will be executed in it's own thread } continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Example Example Program: ThreadCaller class CntThread extends Thread { String ThreadName=""; CntThread(String Name) { this.ThreadName=Name; } Thread Code public void run() { for (int I=0; I<=5; I++) { System.out.println ("Thread " + ThreadName + " :"+I); } } } continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Example class ThreadCaller { public static void main(String args[]) { CntThread Cnt1 = new CntThread("U.S.A. "); CntThread Cnt2 = new CntThread("Germany"); Cnt1.start(); Cnt2.start(); } } Create Thread Objects Start Threads Programming in Java, Helmut Dispert Java Fachbereich Informatik und Elektrotechnik Java Thread Example Expectation: 1st Test Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread 2nd Test U.S.A. Germany U.S.A. Germany Germany U.S.A. Germany Germany Germany U.S.A. U.S.A. U.S.A. :0 :0 :1 :1 :2 :2 :3 :4 :5 :3 :4 :5 Programming in Java, Helmut Dispert Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Germany U.S.A. U.S.A. U.S.A. Germany U.S.A. U.S.A. U.S.A. Germany Germany Germany Germany :0 :0 :1 :2 :1 :3 :4 :5 :2 :3 :4 :5 Fachbereich Informatik und Elektrotechnik Java Thread Example Results (I = 5): 1st Test Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread 2nd Test U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. Germany :0 :0 :1 :1 :2 :2 :3 :3 :4 :4 :5 :5 Programming in Java, Helmut Dispert Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. Germany :0 :0 :1 :1 :2 :2 :3 :3 :4 :4 :5 :5 ordered sequence Fachbereich Informatik und Elektrotechnik Java Thread Example Results (I = 1000): 1st Test Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. Germany U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. 2nd Test :985 :997 :986 :998 :987 :999 :988 :1000 :989 :990 :991 :992 :993 :994 :995 :996 :997 :998 :999 :1000 Programming in Java, Helmut Dispert Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread U.S.A. Germany U.S.A. Germany U.S.A. Germany Germany Germany Germany U.S.A. Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany :997 :985 :998 :986 :999 :987 :988 :989 :990 :1000 :991 :992 :993 :994 :995 :996 :997 :998 :999 :1000 Fachbereich Informatik und Elektrotechnik Java Thread Methods public static void sleep(long millis) throws InterruptedException Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds. The thread does not lose ownership of any monitors. Parameters: millis - the length of time to sleep in milliseconds. public static void sleep(long millis, int nanos) throws InterruptedException Causes the currently executing thread to sleep (cease execution) for the specified number of milliseconds plus the specified number of nanoseconds. The thread does not lose ownership of any monitors. Parameters: millis - the length of time to sleep in milliseconds. nanos - 0-999999 additional nanoseconds to sleep. continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Methods public static void yield() throws InterruptedException Causes the currently executing thread object to temporarily pause and allow other threads to execute. Sleep() actively suspends the thread for the specified time. yield() will give another waiting thread a chance. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Java Thread Example Example Program: ThreadCaller with sleep() ThreadCaller2 class CntThread2 extends Thread { String ThreadName=""; CntThread2(String Name) { this.ThreadName=Name; } public void run() { for (int I=0; I<=10; I++) { System.out.println("Thread " + ThreadName + " :"+I); try { sleep((long) (Math.random() * 1000)); } catch(InterruptedException e) {} } }} sleep() Programming in Java, Helmut Dispert Java Fachbereich Informatik und Elektrotechnik Java Thread Example Results with sleep() (I = 5): 1st Test Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread 2nd Test U.S.A. Germany U.S.A. Germany U.S.A. Germany Germany U.S.A. U.S.A. Germany U.S.A. Germany :0 :0 :1 :1 :2 :2 :3 :3 :4 :4 :5 :5 Programming in Java, Helmut Dispert Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Germany U.S.A. Germany U.S.A. Germany Germany U.S.A. U.S.A. Germany U.S.A. Germany U.S.A. :0 :0 :1 :1 :2 :3 :2 :3 :4 :4 :5 :5 Fachbereich Informatik und Elektrotechnik Java Thread Example Alternative Solution: class ThreadCallerR { public static void main(String args[]) { CntThread Cnt1 = new CntThread("U.S.A. "); CntThread Cnt2 = new CntThread("Germany"); Cnt1.run(); Cnt2.run(); } Run Threads } Java ThreadCallerR Programming in Java, Helmut Dispert Simple Method Call Fachbereich Informatik und Elektrotechnik Java Thread Example Results for the alternative solution (I = 20): 1st Test Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany 2nd Test :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 Programming in Java, Helmut Dispert Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 Fachbereich Informatik und Elektrotechnik Java Thread Example Results for the alternative solution with sleep() (I = 20): 1st Test Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany 2nd Test :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 Programming in Java, Helmut Dispert Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. U.S.A. Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany Germany :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 :0 :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 Fachbereich Informatik und Elektrotechnik Synchronization Synchronization among threads Problem: producer/consumer relationship threads often need to share a common resource (file, etc.) with one thread reading from it while another thread is writing to it. Race conditions: race conditions occur when multiple, asynchronously executing threads access the same object returning unexpected (wrong) results; race conditions can be avoided by synchronizing the methods which access the shared resource. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem Basic Idea: The producer generates an integer (0 to 9) and stores it in an object (Storage); The consumer consumes the integers from the Storage object; Producer and consumer share data through a common Storage object. Ref.: Sun Microsystems Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem No Synchronization: class Storage { private int contents; private boolean available = false; public int get() { available = false; return contents; } public void put(int value) { contents = value; available = true; } } continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem class Producer extends Thread { private Storage stored; private int number; public Producer(Storage c, int number) { stored = c; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { stored.put(i); System.out.println("Producer #" + this.number + " put: " + i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } } Programming in Java, Helmut Dispert continued Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem class Consumer extends Thread { private Storage stored; private int number; public Consumer(Storage c, int number) { stored = c; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = stored.get(); System.out.println("Consumer #" + this.number + " got: " + value); } } } continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem public class PCTest { public static void main(String[] args) { Storage c = new Storage(); Producer p1 = new Producer(c, 1); Consumer c1 = new Consumer(c, 1); p1.start(); c1.start(); } Create Thread Objects } Start Threads Java Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem Results: 1st Test Producer Consumer Consumer Consumer Consumer Consumer Consumer Consumer Consumer Consumer Producer Consumer Producer Producer Producer Producer Producer Producer Producer Producer 2nd Test #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 put: got: got: got: got: got: got: got: got: got: put: got: put: put: put: put: put: put: put: put: 0 0 0 0 0 0 0 0 0 0 1 1 2 3 4 5 6 7 8 9 Programming in Java, Helmut Dispert Producer Consumer Consumer Consumer Consumer Consumer Consumer Consumer Consumer Consumer Consumer Producer Producer Producer Producer Producer Producer Producer Producer Producer #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 put: got: got: got: got: got: got: got: got: got: got: put: put: put: put: put: put: put: put: put: 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 Fachbereich Informatik und Elektrotechnik Synchronization Synchronizing two threads Two types of thread synchronization can be distinguished: Mutual exclusion synchronization: used to protect certain critical sections of code from being executed simultaneously by two threads. Signal-wait synchronization: used when one thread has to wait until another thread has completed its action. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Synchronization Mutual exclusion synchronization: thread 1 thread 2 load store load Context switch Programming in Java, Helmut Dispert store load store load store Context switch Fachbereich Informatik und Elektrotechnik Synchronization Java program: Statements are compiled as a sequence of bytecodes, code is executed using the VM stack (temp values, results), each Java thread has its own stack used to execute bytecodes. Context switch: When VM switches from one running thread to another, it also switches to another stack. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Synchronization Java platform dependence: Atomicity in Java: difficult to write truly platform-independent multithreaded Java programs, because the implementation of atomic operations depend on the OS-level concept. Examples: assignment to variables of most types is atomic, assignment to long or double is not atomic. shortcut operators do not support atomicity, e.g. "x = ++y" or "x += y" could be preempted after the increment operation but before the assignment. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Monitors Monitors: The Java language and runtime system support thread synchronization through the use of monitors C. A. R. Hoare: An Operating System Structuring Concept (Communications of the ACM, 17(10), 549-557, 1974). Reader Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Tony Hoare Sir Charles Antony Richard Hoare (Tony Hoare) One of the fathers of modern computer science, having made fundamental contributions to the definition and design of programming languages. http://research.microsoft.com/users/thoare/ "I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies." Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Tony Hoare Tony Hoare: 1934: born in Colombo (Sri Lanka) 1956: BA in Literae Humaniores (Classics) 1968: appointed as Professor of Computing Science at the Queen's University, Belfast 1977: Professor of Computing at Oxford University developed Quicksort developed the formal language: Communicating Sequential Processes (CSP) (interactions of concurrent processes) 1980: Turing Award since 1999: Emeritus Professor of Computing, Oxford University Computing Laboratory, Senior researcher with Microsoft Research in Cambridge Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Thread Synchronization - Monitors A monitor is associated with a specific data item (a condition variable) and functions as a lock on that data. When a thread holds the monitor for some data item, other threads are locked out and cannot inspect or modify the data. The code segments within a program that access the same data from within separate, concurrent threads are known as critical sections. In the Java language, critical sections in a program are marked with the synchronized keyword. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Thread Synchronization - Monitors To avoid corruption of data during the execution of threads Java provides two levels of thread synchronization: a) Protection of shared resources Locking an Object; b) Signalling between threads to indicate changes in conditions. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Synchronized Methods Protection of shared resources, Locking an Object: The code segments within a program that access the same object from separate, concurrent threads are called critical sections. In the Java language, a critical section can be a block or a method and are identified with the synchronized keyword. The Java platform associates a lock with every object that has synchronized code. Ref.: Sun Microsystems Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Thread Synchronization - Monitors Signalling between threads to indicate changes in conditions. Several methods exist to indicate to a thread when a condition that it is waiting for has been met: - wait() notify() notifyAll() Copyright (c) Galileo Press GmbH 2004 Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Thread Synchronization - Monitors Synchronization Methods public final void wait() Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. public final void notify() Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. public final void notifyAll() Wakes up all threads that are waiting on this object's monitor. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem Example with Synchronization: class Storage { private int contents; private boolean available = false; public synchronized int get() { while (available == false) { try { wait(); } catch (InterruptedException e) { } } available = false; notifyAll(); return contents; } continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem With Synchronization: public synchronized void put(int value) { while (available == true) { try { wait(); } catch (InterruptedException e) { } } contents = value; available = true; notifyAll(); } } Java PCTestSync.java continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Producer/Consumer Problem Results: 1st Test Consumer Producer Producer Consumer Producer Consumer Consumer Producer Consumer Producer Consumer Producer Producer Consumer Producer Consumer Producer Consumer Consumer Producer 2nd Test #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 got: put: put: got: put: got: got: put: got: put: got: put: put: got: put: got: put: got: got: put: 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 Programming in Java, Helmut Dispert Producer Consumer Producer Consumer Producer Consumer Consumer Producer Producer Consumer Producer Consumer Producer Consumer Consumer Producer Producer Consumer Producer Consumer #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 #1 put: got: put: got: put: got: got: put: put: got: put: got: put: got: got: put: put: got: put: got: 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 Fachbereich Informatik und Elektrotechnik Ending a Thread A thread normally ends when it's execution completes, most other methods of stopping a thread are deprecated public void interrupt() Interrupts this thread public boolean isInterrupted() Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method. public final void join() Waits for this thread to die: one thread can wait for another to complete, invoking join() guarantees that the method will not return until the threads run() method has completed. public static void yield() Causes the currently executing thread object to temporarily pause and allow other threads to execute (lower priority threads are ignored). Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Ending a Thread public final void setDaemon(boolean on) Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads. Parameters: on - if true, marks this thread as a daemon thread. Daemon Threads: By default a new thread is not a daemon thread. However a thread can be turned into a daemon thread using the method setDaemon(true). Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Ending a Thread Deprecated methods to stop a thread: public final void stop() Forces the thread to stop executing. stop() is a deprecated method and should not be used. public final void suspend() Suspends this thread. public final void resume() Resumes a suspended thread. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Ending a Thread Ending a Thread using "interrupt()" • interrupt() setzt eine interne Variable auf true, die in der run() – Methode abgefragt werden kann. • isInterrupted() wird in der run() – Methode aufgerufen um zu überprüfen, ob der Thread beendet werden soll. Diese Methode sollte regelmäßig in der run() – Methode aufgerufen werden. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Ending a Thread class ThreadInterrupt extends Thread { public void run() { System.out.println( "Der Anfang" ); while ( ! isInterrupted() ) { System.out.println( "Und er laeuft und er laeuft und er laeuft" ); try { Thread.sleep( 500 ); } catch ( InterruptedException e ) { interrupt(); System.out.println( "Unterbrechung in sleep()" ); } } System.out.println( "Das Ende" ); continued } Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Ending a Thread public static void main( String args[] ) { ThreadInterrupt t = new ThreadInterrupt(); t.start(); try { Thread.sleep( 5000 ); } catch ( InterruptedException e ) { } t.interrupt(); } } Java Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Ending a Thread using join() Using "join()" to wait for the end of a thread • Threads können beim Beenden keine Ergebnisse nach außen geben, dafür verwendet man Klassen oder Objekt –Variablen. • Andere Threads wissen aber nicht, wann ein bestimmter Thread fertig ist. • Daher warten diese Threads mit Hilfe der Methode join() auf deren Beendigung. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example: Ending a Thread using join() class JoinTheThread { static class JoinerThread extends Thread { public int result; public void run() { result = 1; } } public static void main( String args[] ) throws Exception { JoinerThread t = new JoinerThread(); t.start(); t.join(); // Ohne diesen Aufruf ist das Resultat 0 – mit ist es 1 // Kann wahlweise auch mit einem Timeout versehen werden System.out.println( t.result ); } } Java Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Waiting for the slowest thread Zwei Threads A und B arbeiten an einem Problem. Die Methode go() startet A und B und wartet dann, bis beide fertig sind. Dann kann ein weiterer Thread die Ergebnisse verwenden. void go() throws Exception { Thread a = new A(); Thread b = new B(); a.start(); b.start(); a. join() ; b. join() ; } Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Putting a thread to sleep Um einen Thread schlafen zu legen, verwendet man die Methode sleep() : public class SleepInInnerClass { public static void main( String args[] ) { new Thread() { { start(); } { public void run() { try { sleep(2000); System.out.println("Zeit ist um."); } catch ( InterruptedException e ) { } } } }; } } Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Stopping and resuming a thread • Mit den folgenden Methoden kann man einen Thread vorübergehend deaktivieren: – void suspend() Versetzt den Thread in den Zustand „nicht laufend“, bis resume() aufgerufen wird. – void resume() Versetzt ihn wieder in den Zustand „laufend“. • Beide Methoden sind veraltet ("deprecated") und sollten nicht mehr verwendet werden. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Priorities Priorities • Jeder Thread wird auf einer Skala von 1 bis 10 mit der Standardpriorität 5 gestartet. • Die Priorität wirkt sich auf die Häufigkeit, mit der der Thread vom Scheduler ausgeführt wird, aus und kann entweder im Konstruktor oder mit der Methode setPriority() gesetzt werden. • Hohe Prioritäten sollten zugunsten von niedrigeren Prioritäten vermieden werden. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Example Example Applets and Threads continued Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Clock-Applet import import import import import java.awt.*; java.awt.Graphics; java.util.*; java.text.DateFormat; java.applet.Applet; Clock implements the Runnable interface (and therefore implements the run method defined in it) public class Clock extends Applet implements Runnable { private Thread clockThread = null; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e){ } } continued } Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Clock-Applet public void paint(Graphics g) { // get the time and convert it to a date Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); // format it and display it DateFormat dateFormatter = DateFormat.getTimeInstance(); Font arial200 = new Font ("Arial", Font.PLAIN, 200); g.setFont(arial200); g.drawString(dateFormatter.format(date), 75, 250); } // overrides Applet's stop method, not Thread's public void stop() { clockThread = null; } } <HTML> <HEAD> <TITLE>Clock</TITLE> </HEAD> <BODY> <APPLET CODE= "Clock.class" WIDTH=900 HEIGHT = 300> </APPLET> </BODY> </HTML> Programming in Java, Helmut Dispert Demo Fachbereich Informatik und Elektrotechnik Clock-Applet Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Programming Errors Programming errors Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Programming Errors Common Programming Errors in multithreaded programs: 1. Race condition: Two threads with references to a shared object interfere with each other. 2. Deadlock: A thread in a group of threads is holding one lock and waiting for another lock that is held by another thread in the group. Consequence: not simply possible to add synchronized to all methods. Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Deadlock Copyright (c) Galileo Press GmbH 2004 Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Programming Errors Deadlock: Thread 1 Wait for lock for objectOne Enter methodOne() for objectOne Context switch Thread 2 Wait for lock for objectTwo Enter methodOne() for objectTwo Call ObjectTwo.methodTwo() Wait for lock for objectTwo Call ObjectOne.methodTwo() Wait for lock for objectOne Both waiting Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Deadlock Example class Deadlock { static Object a = new Object(), b = new Object(); static class T1 extends Thread { public void run() { synchronized( a ) { System.out.println( "T1: Get lock on a" ); waitDelay(); synchronized( b ) { System.out.println( "T1: Get lock on b" ); } } } private void waitDelay() { try { Thread.sleep( 1000 ); } catch ( InterruptedException e ) { } } } Programming in Java, Helmut Dispert Fachbereich Informatik und Elektrotechnik Deadlock Example static class T2 extends Thread { public void run() { synchronized( b ) { System.out.println( "T2: Get lock on b" ); synchronized( a ) { System.out.println( "T2: Get lock on a" ); } } } } public static void main( String args[] ) { new T1().start(); new T2().start(); } } T1: Get lock on a T2: Get lock on b Programming in Java, Helmut Dispert Java Fachbereich Informatik und Elektrotechnik Threadgroups "main" subgroup1 subgroup2 subgroup3 Thread-β β Thread-α α Thread-A Thread-1 Thread-3 Thread-2 Thread-a Thread-d Thread-b Thread-c Programming in Java, Helmut Dispert