Java threads: Introduction

27
1 Java threads: Introduction

description

Java threads: Introduction. Topics. background, motivation, and benefits of threads what is a Java thread how to start a thread how to stop a thread (if possible) on implementation of threads scheduling policies, priorities, etc. threads and interrupts - PowerPoint PPT Presentation

Transcript of Java threads: Introduction

Page 1: Java threads: Introduction

1

Java threads: Introduction

Page 2: Java threads: Introduction

2

Topics

• background, motivation, and benefits of threads• what is a Java thread

– how to start a thread– how to stop a thread (if possible)

• on implementation of threads– scheduling policies, priorities, etc.

• threads and interrupts – on interrupting and stopping threads

Page 3: Java threads: Introduction

3

Concurrent programming in Java

• in multiprocessing, multiple operating-system level processes are used to execute (independent) programs– the programs execute in their own (usually

protected) memory spaces, using their own (virtual) CPUs

• in multithreading, each thread also executes concurrently, with its own logical copy of CPU (program counter, registers, stack, cache, etc.), – however, all threads can potentially share and

access the same data (global objects) in the program

Page 4: Java threads: Introduction

4

Concurrent programming (cont.)

• process ~ a concurrent execution of a program (e.g., the Java virtual machine)

• thread ~ a concurrent control flow in the same program (process)

• can involve either CPU interleaving vs. actual parallelism with multiple CPUs– "concurrent" activities may be only interleaved

with the same CPU, or – execution can be truly parallel with multiple CPUs

Page 5: Java threads: Introduction

5

Benefits of multithreading

1. to modularize the system by defining independent activities (to separate concerns, and to remove dependencies)

2. to model simultaneous activities taking place in the real world or in the system– receiving and dispatching GUI events

(keyboard input, button clicks etc.) – animation, rendering graphical models, ..

3. to utilize idle waiting times for better performance

4. to increase responsiveness while occupied with any lenghty tasks, such as – IO, accessing e-mail, downloading files, etc.

Page 6: Java threads: Introduction

6

What are Java threads?

• threads are mostly independent activities• threads may need to share memory = objects in Java• multiple threads can use the same re-entrant code

– but handling of shared objects must be protected by specially identified critical sections of code

• each thread has its own program counter (PC)• a stack (plus registers, caches, ..) is needed for

expression evaluation and method calls per thread– exceptions propagate along the call stack of an

individual thread– if not caught, an exception causes the termination

of that thread, only

Page 7: Java threads: Introduction

7

Java concurrency features

• API class java.lang.Thread, with the run () method as its "main"

• so-called monitor locks and condition (wait) queues • a lot of different synchronization facilities• threads may have priorities

• threads are implemented by the JVM (Java Virtual Machine) but

• their behaviour is heavily influenced by the underlying operating system and its characteristics– e.g., handling of scheduling, priorities, interrupting

on-going IO activity, etc.

Page 8: Java threads: Introduction

8

How to start a thread (1)

public interface java.lang.Runnable {

void run ();

}

class MyRunnable implements java.lang.Runnable {

public void run () {

task to be done. .

}

}

new java.lang.Thread (new MyRunnable ()).start ();

• start () creates a new execution context (program counter, stack, cache, etc.) for the new thread, and then returns, in the old thread

Page 9: Java threads: Introduction

9

The Runnable interface

• a Thread stores the reference to a Runnable, and when later started, begins to execute its run method

• a single Runnable object may be shared by multiple threads that are thus executing the same code and possibly sharing the same data

• we may use an inner Runnable class to define a task to be executed by a thread:

runner = new Runnable () {

public void run () {

/* thread activity ... */ }};

new Thread (runner).start ();

Page 10: Java threads: Introduction

10

How to start a thread (2)• you can also define a subclass of the Thread class

class MyThread extends java.lang.Thread {

public void run () {

task to be done . .

}

new MyThread ().start ();

• not recommended: better to decouple the task to run from the mechanism of running it– if you have many tasks, it may be too expensive to

create a separate thread for each one of them• a thread reserves resources from the OS• too many threads may throttle the system

Page 11: Java threads: Introduction

11

How to stop a thread

• usually, a thread stops when its run method returns:

public void run () {

task to be done . .

}

• you cannot force a thread to stop from outside– such abort could cause undetermined state

• instead, set a variable to indicate that the thread should stop; the thread itself checks this variable regularly, and can return from its run method in an orderly fashion – or, you can interrupt a waiting thread, see later

Page 12: Java threads: Introduction

12

Daemon threads

• a thread can be made a daemon thread before it is started:

      aThread.setDaemon (true);

• daemons are service threads that execute background tasks (say, signaling timer events)

• the program exits, when only daemons are left – there is no point in keeping the program running

if all remaining threads are daemons

• the GUI event thread is not a daemon (of course); a garbage collection could (possible) be..

Page 13: Java threads: Introduction

13

Implementation of threads

• the actual scheduling policy is system-dependent, and determined together by the host OS and the VM implementation:

– scheduling between multiple threads may be preemptive using time-slicing techniques, so that activities become (randomly) interleaved

• operating system may not guarantee fairness

– or, in principle, it could be non-preemptive where each thread must itself voluntarily give turn to others

• also called: "cooperative"• nowadays, less seldomly used

Page 14: Java threads: Introduction

14

Implementation of threads (cont.)• historically, "green threads" were simulated threads

within the VM and were used prior to Java 1.2– not mapped to kernel threads provided by the OS– non-preemptive scheduling: yield or sleep– easier and more portable implementation

• yield (): the currently executing thread object pauses and allows other threads to execute

• "native threads" are provided by the host operating system – native threads can realize the performance

enhancements, e.g., from parallelism (with multiple CPUs)

– after Just-In-Time compiler (Java HotSpot VM), a Java thread corresponds to a native OS thread

Page 15: Java threads: Introduction

15

Thread priorities

• priority is between Thread.MIN_PRIORITY and Thread.MAX_PRIORITY

• these are currently defined as 1 and 10, respectively • Thread.NORM_PRIORITY is currently defined as 5

• by default, a thread inherits its parent's priority, or a new priority may be specified:

aThread.setPriority (newPriorityLevel);

• usually, the scheduler tends to prefer higher-priority threads

Page 16: Java threads: Introduction

16

Thread priorities (cont.)

• however, the host platform may map these (ten) levels into fewer priority levels, or even ignore all priorities – Windows NT/XP had 7 priority levels; in some

JVMs, all threads have the same priority– an apparently "lower"-priority thread may thus

preempt a "higher"-priority thread • consequently, priorities can only be used to

heuristically tune performance or enhance responsiveness – especially, thread priorities cannot be used to

solve synchronization or exclusion problems in any portable way

Page 17: Java threads: Introduction

17

Thread priorities (cont.)

• furthermore, Java VM specification gives no guarantee of general fairness in thread scheduling – but of course good implementations try to achieve

it in their own ways

• Thread.yield () is a hint that the current thread wouldn't mind giving processing time to other threads

• in platforms with non-preemptive scheduling, yield is the main way to give other threads a chance to run

• moreover, in some platforms, yield may be ignored, so generally Thread.sleep (delay) is a more reliable way to give turn to other threads

Page 18: Java threads: Introduction

18

Interrupting threads

• normally, a thread terminates when its run () returns• but you can try to interrupt it by:

thread.interrupt ();

• requests the thread to cancel its activities – when it feels itself ready for it..

• if a thread is running then its interrupted status flag will be set on to be tested by the thread– however, if a thread is somehow blocked, it

cannot itself inspect for an interruption • if waiting (e.g., wait, sleep, or join), the interrupted

thread throws the checked InterruptedException (the interrupt flag is not set on):

Page 19: Java threads: Introduction

19

Interrupting threads (cont.)

void run () {

try {

while (!Thread.interrupted () && more work)

. . // may block and throw..

} catch (InterruptedException e) {

. . // interrupted during its sleep or wait . .

} finally {

. . // cleanup in any case

}

} // exiting from run terminates the thread• InterruptedException is a checked exception, so you

must catch it, or mark your methods with it

Page 20: Java threads: Introduction

20

Interrupting threads (cont.)

• thread.isInterrupted () tests the "interrupted" flag• Thread.interrupted () can be called only by the

current thread itself and also cleares the flag

• as always, it is bad style to just ignore exceptions:

void mySubTask () { . . .

try { . . . }

catch (InterruptedException e) { } // DON'T

. . .

• tag the method to throw InterruptedException, or• at least call interrupt () again in the handler to set

the interrupted status so that the caller can test it

Page 21: Java threads: Introduction

21

Idioms for interrupting threads

(1) if goes to sleep, no need to separately test the flag:

try { . . .

while (more work to do) {do more workThread.sleep (delay); // clears flag

}

} catch (InterruptedException e) {

// handle interruption during sleep or wait

} finally {

cleanup, if required

}

• but interruptions are not errors but stop requests

Page 22: Java threads: Introduction

22

Idioms for interrupting threads (cont.)

(2) in a method, catch but don't "handle" and instead set the interrupted flag back on:

try { . .

Thread.sleep (delay); // clears flag

} catch (InterruptedException e) {

. . Thread.currentThread ().interrupt (); // set flag

}

// . . and test the flag somewhere else

// any sleep or wait will again throw the exception• could also declare that the method throws, but then

intermediate callers must handle the same possibility

Page 23: Java threads: Introduction

23

Idioms for interrupting threads (cont.)

(3) sometimes, can itself forward the "interrupted" state with an exception to be caught elsewhere:

if (Thread.currentThread ().isInterrupted ()) throw new InterruptedException (); // don't clear

Warning: an IO operation is either interrupted or not: may depend on the platform/implementation (see [Arnold et al., The Java Prog. Lang., 2006, p. 367])

• if a thread is blocked by a monitor lock, it won't throw InterruptedException but the flag is set on– the wait may later throw the interruption– special ReentrableLock objects (5.0) can throw,

however..

Page 24: Java threads: Introduction

24

Why cannot simply stop a thread

• Java version 1.0 methods stop (), suspend (), and resume () have been deprecated as unsafe

• stop threw unchecked ThreadDeath that was meant not to be caught (but no guarantees) – a severe violation of exception safety: may break

class invariants (in totally indeterministic way)– additionally, can cause deadlocks: a stopped

thread may leave reserved resources

• much safer solutions are provided by – a status variable that a thread checks itself, or – checked InterruptedException and the interrupted

flag (with finally blocks to clean things up)

Page 25: Java threads: Introduction

25

Thread groups

• every thread belongs to a thread group, specified as a constructor parameter or, by default, inherited from the current thread (that is creating the new thread)

• thread groups were part of the original impl. of threads, and were made available to users

• the thread groups form a tree-like structure• can go through all threads in a group, set the max

priority for a group, interrupt a whole group, manage security policies, or override uncaughtException method (since 5.0 also within the class Thread)

• note that, since threads are objects, you can store, access, and control threads using any Java data structures + tools in package java.util.concurrent

Page 26: Java threads: Introduction

26

Summary of Thread methods

• new Thread (aRunnable): create with a Runnable • thread.start (): the thread starts executing • b = thread.isAlive (): is the thread in the Alive state • thread.interrupt (): set flag, or throw (when waiting)• b = thread.isInterrupted (): only test if the flag is set • otherThread.join (): waits that other thread finishes• otherThread.join (millis, nanos): waits with time-out • thread.setDaemon (b): set daemon / a user thread • b = thread.isDaemon (): test if this is a daemon• thread.setPriority (i): set priority (hint to scheduler)• i = thread.getPriority (): get priority• s = thread.toString (): name, priority, thread group,..

Page 27: Java threads: Introduction

27

Summary of static Thread methods

• the thread currently running a CPU (possibly many)

current = Thread.currentThread ();– of course, each thread gets different result (itself)

• also join (implicitly) affects current (waits for other)

• b = Thread.interrupted (): test if the flag of the current thread is set; also clears the flag

• Thread.sleep (millis, nanos): the current thread ceases execution for (at least) the given amout– the thread enters the Blocked state

• Thread.yield (): the current thread "temporarily" pauses (but stays runnable) to give other threads a chance to run