Topics • background, motivation, and benefits of threads • what is a Java thread – how to start a thread – how to stop a thread (if possible) Java threads: Introduction • on implementation of threads – scheduling policies, priorities, etc. • threads and interrupts – on interrupting and stopping threads 1 2 Concurrent programming in Java Concurrent programming (cont.) • in multiprocessing , multiple operating-system level • process ~ a concurrent execution of a program processes are used to execute (independent) (e.g., the Java virtual machine) programs • thread ~ a concurrent control flow in the same – the programs execute in their own (usually program (process) protected) memory spaces, using their own (virtual) CPUs • can involve either CPU interleaving vs. actual parallelism with multiple CPUs • in multithreading , each thread also executes concurrently, with its own logical copy of CPU – "concurrent" activities may be only interleaved (program counter, registers, stack, cache, etc.), with the same CPU, or – however, all threads can potentially share and – execution can be truly parallel with multiple CPUs access the same data (global objects) in the program 3 4 1
Benefits of multithreading What are Java threads? 1. to modularize the system by defining independent • threads are mostly independent activities activities (to separate concerns, and to remove • threads may need to share memory = objects in Java dependencies) • multiple threads can use the same re-entrant code 2. to model simultaneous activities taking place in the – but handling of shared objects must be protected real world or in the system by specially identified critical sections of code – receiving and dispatching GUI events (keyboard input, button clicks etc.) • each thread has its own program counter (PC) – animation, rendering graphical models, .. • a stack (plus registers, caches, ..) is needed for expression evaluation and method calls per thread 3. to utilize idle waiting times for better performance – exceptions propagate along the call stack of an 4. to increase responsiveness while occupied with any individual thread lenghty tasks, such as – if not caught, an exception causes the termination IO , accessing e-mail , downloading files , etc. – of that thread, only 5 6 How to start a thread (1) Java concurrency features public interface java.lang.Runnable { • API class java.lang.Thread , with the run () method as void run (); its "main" } • so-called monitor lock s and condition ( wait ) queues class MyRunnable implements java.lang.Runnable { • a lot of different synchronization facilities public void run () { • threads may have priorities task to be done. . } • threads are implemented by the JVM (Java Virtual } Machine) but new java.lang.Thread (new MyRunnable ()).start (); • their behaviour is heavily influenced by the underlying operating system and its characteristics • start () creates a new execution context (program – e.g., handling of scheduling, priorities, interrupting counter, stack, cache, etc.) for the new thread, and on-going IO activity, etc. then returns, in the old thread 7 8 2
How to start a thread (2) The Runnable interface • you can also define a subclass of the Thread class • a Thread stores the reference to a Runnable , and class MyThread extends java.lang.Thread { when later started, begins to execute its run method public void run () { • a single Runnable object may be shared by multiple task to be done . . threads that are thus executing the same code and } possibly sharing the same data new MyThread ().start (); • we may use an inner Runnable class to define a task to be executed by a thread: • not recommended: better to decouple the task to run from the mechanism of running it runner = new Runnable () { – if you have many tasks, it may be too expensive to public void run () { create a separate thread for each one of them /* thread activity ... */ }}; • a thread reserves resources from the OS new Thread (runner).start (); • too many threads may throttle the system 9 10 How to stop a thread Daemon threads • usually, a thread stops when its run method returns: • a thread can be made a daemon thread before it is public void run () { started: task to be done . . aThread.setDaemon (true); } • daemons are service threads that execute • you cannot force a thread to stop from outside background tasks (say, signaling timer events) – such abort could cause undetermined state • the program exits, when only daemons are left • instead, set a variable to indicate that the thread – there is no point in keeping the program running should stop; the thread itself checks this variable if all remaining threads are daemons regularly, and can return from its run method in an orderly fashion • the GUI event thread is not a daemon (of course); a garbage collection could (possible) be.. – or, you can interrupt a waiting thread, see later 11 12 3
Implementation of threads (cont.) Implementation of threads • historically, " green threads " were simulated threads • the actual scheduling policy is system-dependent, within the VM and were used prior to Java 1.2 and determined together by the host OS and the VM – not mapped to kernel threads provided by the OS implementation: – non-preemptive scheduling: yield or sleep – scheduling between multiple threads may be – easier and more portable implementation preemptive using time-slicing techniques, so that • yield (): the currently executing thread object pauses activities become (randomly) interleaved and allows other threads to execute • operating system may not guarantee fairness • " native threads " are provided by the host operating system – or, in principle, it could be non-preemptive where each thread must itself voluntarily give turn to – native threads can realize the performance others enhancements, e.g., from parallelism (with multiple CPUs) • also called: "cooperative" – after Just-In-Time compiler (Java HotSpot VM), • nowadays, less seldomly used a Java thread corresponds to a native OS thread 13 14 Thread priorities Thread priorities (cont.) • however, the host platform may map these (ten) • priority is between Thread.MIN_PRIORITY and levels into fewer priority levels, or even ignore all Thread.MAX_PRIORITY priorities • these are currently defined as 1 and 10, respectively – Windows NT/XP had 7 priority levels; in some • Thread.NORM_PRIORITY is currently defined as 5 JVMs, all threads have the same priority • by default, a thread inherits its parent's priority, or a – an apparently "lower"-priority thread may thus new priority may be specified: preempt a "higher"-priority thread • consequently, priorities can only be used to aThread.setPriority (newPriorityLevel); heuristically tune performance or enhance responsiveness • usually, the scheduler tends to prefer higher-priority – especially, thread priorities cannot be used to threads solve synchronization or exclusion problems in any portable way 15 16 4
Interrupting threads Thread priorities (cont.) • normally, a thread terminates when its run () returns • furthermore, Java VM specification gives no • but you can try to interrupt it by: guarantee of general fairness in thread scheduling – but of course good implementations try to achieve thread.interrupt (); it in their own ways • requests the thread to cancel its activities • Thread.yield () is a hint that the current thread – when it feels itself ready for it.. wouldn't mind giving processing time to other • if a thread is running then its interrupted status flag threads will be set on to be tested by the thread • in platforms with non-preemptive scheduling, yield is – however, if a thread is somehow blocked, it the main way to give other threads a chance to run cannot itself inspect for an interruption • moreover, in some platforms, yield may be ignored, • if waiting (e.g., wait , sleep , or join ), the interrupted so generally Thread.sleep (delay) is a more reliable thread throws the checked InterruptedException way to give turn to other threads (the interrupt flag is not set on): 17 18 Interrupting threads (cont.) Interrupting threads (cont.) void run () { • thread.isInterrupted () tests the "interrupted" flag try { • Thread.interrupted () can be called only by the while (!Thread.interrupted () && more work ) current thread itself and also cleares the flag . . // may block and throw.. • as always, it is bad style to just ignore exceptions: } catch (InterruptedException e) { void mySubTask () { . . . . . // interrupted during its sleep or wait . . try { . . . } } finally { catch (InterruptedException e) { } // DON'T . . // cleanup in any case . . . } } // exiting from run terminates the thread • tag the method to throw InterruptedException , or • InterruptedException is a checked exception, so you • at least call interrupt () again in the handler to set must catch it, or mark your methods with it the interrupted status so that the caller can test it 19 20 5
Recommend
More recommend