Title: Thread Priorities I
1Thread Priorities I
- Although priorities can be given to Java threads,
they are only used as a guide to the underlying
scheduler when allocating resources - An application, once running, can explicitly give
up the processor resource by calling the yield
method - yield places the thread to the back of the run
queue for its priority level
2Thread Priorities II
package java.lang public class Thread extends
Object implements Runnable //
constants public static final int MAX_PRIORITY
10 public static final int MIN_PRIORITY
1 public static final int NORM_PRIORITY 5
// methods public final int getPriority()
public final void setPriority(int newPriority)
public static void yield() ...
3Warning
- From a real-time perspective, Javas scheduling
and priority models are weak in particular - no guarantee is given that the highest priority
runnable thread is always executing - equal priority threads may or may not be time
sliced - where native threads are used, different Java
priorities may be mapped to the same operating
system priority
4Delaying Threads Clocks
- Java supports the notion of a wall clock
- java.lang.System.currentTimeMillis returns the
number of milliseconds since 1/1/1970 GMT and is
used by used by java.util.Date (see also
java.util.Calendar) - However, a thread can only be delayed from
executing by calling the sleep methods in the
Thread class - sleep provides a relative delay (sleep from now
for X milliseconds, y nano seconds), rather than
sleep until 15th December 2003
5Delaying a Thread
public class Thread extends Object
implements Runnable ... public static
void sleep(long ms) throws
InterruptedException public static void
sleep(long ms, int
nanoseconds) throws InterruptedException
...
6Sleep Granularity
Local drift
Granularity difference between clock and sleep
time
Time specified by program
Thread runnable here but not executing
Interrupts disabled
Time
7Drift
- The time over-run associated with both relative
and absolute delays is called the local drift and
it it cannot be eliminated - It is possible, with absolute delays, to
eliminate the cumulative drift that could arise
if local drifts were allowed to superimpose
while(true) // do action every 1 second
sleep(1000)
8Absolute Delays I
- Consider an embedded system where the software
controller needs to invoke two actions - The causes the environment to prepare for the
second action - The second action must occur a specified period
(say 10 seconds) after the first action has been
initiated - Simply sleeping for 10 seconds after a call to
the first action will not achieve the desired
effect for two reasons - The first action may take some time to execute.
If it took 1 second then a sleep of 10 would be a
total delay of 11 seconds - The thread could be pre-empted after the first
action and not execute again for several seconds - This makes it extremely difficult to determine
how long the relative delay should be
9Absolute Delays II
static long start static void action1()
... static void action2() ... try
start System.currentTimeMillis()
action1() Thread.sleep( 10000 -
(System.currentTimeMillis() - start))
catch (InterruptedException ie) ...
action2()
What is wrong with this approach?
10Timeout on Waiting I
- In many situations, a thread can wait for an
arbitrary long period time within synchronized
code for an associated notify (or notifyAll) call - There are occasions when the absence of the call,
within a specified period of time, requires that
the thread take some alternative action - Java provides two methods for this situation both
of which allows the wait method call to timeout - In one case, the timeout is expressed in
milliseconds in the other case, milliseconds and
nanoseconds can be specified
11Timeout on Waiting II
- There are two important points to note about this
timeout facility - As with sleep, the timeout is a relative time and
not an absolute time - It is not possible to know for certain if the
thread has been woken by the timeout expiring or
by a notify - There is no return value from the wait method and
no timeout exception is thrown
12Timeouts on Waiting
public class TimeoutException extends
Exception public class TimedWait public
static void wait(Object lock, long millis)
throws InterruptedException, TimeoutException
// assumes the lock is held by the caller
long start System.currentTimeMillis()
lock.wait(millis) if(System.currentTimeMillis
() gt start millis) throw new
TimeoutException()
What is wrong with this approach?
13Thread Groups I
- Thread groups allow collections of threads to be
grouped together and manipulated as a group
rather than as individuals - They also provide a means of restricting who does
what to which thread - Every thread in Java is a member of a thread
group - There is a default group associated with the main
program, and hence unless otherwise specified,
all created threads are placed in this group
14Thread Groups II
public class ThreadGroup public
ThreadGroup(String name) // Creates a new
thread group. public ThreadGroup(ThreadGroup
parent, String name) // Creates a new group
with the // specified parent. . . .
public final void interrupt() // Interrupt
all threads in the group. public void
uncaughtException(Thread t,
Throwable e) // Called if a
thread in the group // terminates due to an
uncaught exception.
15Thread Groups III
- Hierarchies of thread groups to be created
- Thread groups seem to have fallen from favour in
recent years - The deprecation of many of its methods means that
there is little use for it - However, the interrupt mechanisms is a useful way
of interacting with a group of threads - Also, the uncaughtException method is the only
hook that Java 1.4 provides for recovering when a
thread terminates unexpectedly
16Processes
- Threads execute within the same virtual address
space and, therefore, have access to shared
memory. - The Java languages acknowledges that the Java
program might not be the only activity on the
hosting computer and that it will executing under
control of an operating system - Java, therefore, allows the programmer to create
and interact with other processes under that host
system - Java defines two classes to aid this interaction
- java.lang.Process
- java.lang.Runtime
- (look them up on the web and in the book)
17Strengths of the Java Concurrency Model
- The main strength is that it is simple and it is
supported directly by the language - This enables many of the errors that potentially
occur with attempting to use an operating system
interface for concurrency do not exists in Java - The language syntax and strong type checking
gives some protection - E.g., it is not possible to forget to end a
synchronized block - Portability of programs is enhanced because the
concurrency model that the programmer uses is the
same irrespective of on which OS the program
finally executes
18Weaknesses I
- Lack of support for condition variable
- Poor support for absolute time and time-outs on
waiting - No preference given to threads continuing after a
notify over threads waiting to gain access to the
monitor lock for the first time - Poor support for priorities
Note Java 1.5 concurrency utilities will provide
some help here
19Weaknesses II
- Synchronized code should be kept as short as
possible - Nested monitor calls
- should be avoided because the outer lock is not
released when the inner monitor waits (to release
the lock causes other problems) - can lead to deadlock occurring
- It is not always obvious when a nested monitor
call is being made - methods in a class not labelled as synchronized
can still contain a synchronized statement - methods in a class not labelled as synchronized
can be overridden with a synchronized method
method calls which start off as being
unsynchronized may be used with a synchronized
subclass - methods called via interfaces cannot be labelled
as synchronized
20Blochs Thread Safety Levels I
- Immutable
- Objects are constant and cannot be changed
- Thread-safe
- Objects are mutable but they can be used safely
in a concurrent environment as the methods are
synchronized - Conditionally thread-safe
- Objects either have methods which are
thread-safe, or have methods which are called in
sequence with the lock held by the caller
21Blochs Thread Safety Levels II
- Thread compatible
- Instances of the class provide no synchronization
- However, instances of the class can be safely
used in a concurrent environment, if the caller
provides the synchronization by surrounding each
method (or sequence of method calls) with the
appropriate lock - Thread-hostile
- Instances of the class should not be used in a
concurrent environment even if the caller
provides external synchronization - Typically a thread hostile class is accessing
static data or the external environment
22Summary I
- Threads can have priorities but support is weak
- Threads can delay themselves by using the sleep
methods which only supports relative time periods
(intervals) it is not possible to accurately
sleep until an absolute time - Time-outs of waiting for events is supported via
the wait methods but it is not easy to determine
whether the timeout has expired or the event has
occurred - Threads can be grouped together via the
ThreadGroup class - Hierarchies of groups can be formed and it is
possible to interrupt the whole group
23Summary II
- Interaction with processes outside the virtual
machine via the Processes and RunTime classes - The Java model has both strengths and weaknesses
- Blochs has defined thread safety levels