You are on page 1of 11

Concurrent programming features

Q: What is threaded programming and when is it used?

A: Threaded programming is normally used when a program is


required to do more than one task at the same time.
Threading is often used in applications with graphical user
interfaces; a new thread may be created to do some
processor-intensive work while the main thread keeps the
interface responsive to human interaction.

The Java programming language has threaded programming


facilities built in, so it is relatively easy to create threaded
programs. However, multi-threaded programs introduce a
degree of complexity that is not justified for most simple
command line applications.

Q: What is a thread?

A: In Java the Thread class represents a single independent


path of execution in a Java Virtual Machine. When you run a
Java program it implicitly starts a single thread of execution.
The Thread class enables programmers to create additional
threads and set them running. A number of threads may run
in parallel, but only one is actively executed at a given
moment.

The Java runtime system uses fairly complex thread


scheduling mechanisms to coordinate the execution of
threads, but this does not require privileged knowledge or
detail level intervention by programmers. Programmers can
manage the high level creation, initiation and distribution of
tasks amongst threads through simple Application
Programming Interface (API) methods.

The example below shows the simplest approach to thread


creation and task execution; construct a new Thread with a
Runnable argument and start it.

Q: How do Java threads make the environment asynchronous?

A: The thread mechanism in Java begins with the main entry


point thread the runtime environment creates to start a Java
program. When you use that initial thread create secondary
threads, each one runs independently of the other. The Java
virtual machine manages the execution of the threads so they
behave as if they all run at the same time, in fact each thread
briefly takes turns at execution.
In its simplest form there may be no communication or
synchronization between multiple threads in a Java program
and they each run to completion independently of each other.
In this respect Java threads are fundamentally asynchronous,
there is no master clock that governs when threads will run
and when they synchronize variables to “catch-up” with each
other.

It is often necessary and more useful if threads do check


ready states before progressing, synchronize read and write
access to shared variables and call-back to each other when
their work is done. This is where the synchronized keyword and
the various sleep(), wait() and notify() methods are used to more
closely schedule the interaction between asynchronous
threads.

Threads and runnable types


Q: What's the difference between Thread and Runnable types?

A: A Java Thread controls the main path of execution in an


application. When you invoke the Java Virtual Machine with
the java command, it creates an implicit thread in which to
execute the main() method. The Thread class provides a
mechanism for the first thread to start-up other threads to run
in parallel with it.

The Runnable interface defines a type of class that can be run


by a thread. The only method it requires is run(), which makes
the interface very easy to fulfil by extending existing classes.
A runnable class may have custom constructors and any
number of other methods for configuration and manipulation.

Q: What is a Runnable object and a Runnable argument?

A: A Runnable object is one that implements the Runnable


interface, which is the type used to execute new threads. The
Runnable interface only has one method, run(), which must be
implemented by a Runnable class.

In Java an argument is a primitive value or object reference


that is passed to a constructor or method, defined in the
method signature. A Runnable argument would be a constructor
or method argument that is declared to be a Runnable type.
The constructor of the Thread class is the most obvious
example.

public Thread(Runnable target);


This constructor requires a Runnable type argument to be
passed when a Thread is instantiated.

Q: How does the run() method in Runnable work?

A: It may help to think of the run method like the main method
in standard single threaded applications. The run method is a
standard entry point to run or execute a class. The run method
is normally only executed in the context of an independent
Thread, but is a normal method in all other respects.

Q: A Thread is runnable, how does that work?

A: The Thread class' run() method normally invokes the run()


method of the Runnable type it is passed in its constructor.
However, it is possible to override the thread's run method
with your own.

It is more common to implement the Runnable interface in a


separate class and pass it to a standard Thread constructor.
This approach usually requires less coding and allows your
Runnable class to inherit useful application-specific behaviour
from a separate class hierarchy.

Q: Do Thread and Runnable types have their own run() methods?

A: The Runnable interface defines an abstract run() method and


the Thread class implements the interface, so has its own
concrete run() method. However the Thread class
implementation of run() is different from most others because
of its special use in the creation of new threads.

In a typical Runnable class the run() method contains code that


does the main work of a thread. It may complete one long-
running process or set up a loop that repeats a series of
actions, for example. The Thread run() method has no “worker”
code of its own, it just calls the run() method of the Runnable
object that was passed to its constructor.

To instantiate a Thread object you normally pass a Runnable


class to the constructor as the “target” of the thread. When
you call the Thread's start() method it creates a new thread
whose first and only action is the to call Thread class' own run()
method once. The Thread class run() calls the run() method on
the target Runnable, which does the work of the thread.

Q: Why not override Thread to make a Runnable?


A: There is little difference in the work required to override the
Thread class compared with implementing the Runnable
interface, both require the body of the run() method to be
implemented. However, it is much simpler to make an existing
class hierarchy runnable because any class can be adapted to
implement the run() method. A subclass of Thread cannot
extend any other type, so application-specific code would
have to be added to it rather than inherited.

Separating the Thread class from the Runnable implementation


also avoids potential synchronization problems between the
thread and the run() method. A separate Runnable generally
gives greater flexibility in the way that runnable code is
referenced and executed.

Q: When could I adapt the Thread class though?

A: It is always best to implement a Runnable type rather than


extend a Thread. On that basis, the extension of the Thread
class should only be considered in exceptional circumstances
when the application is very simple, composed of few classes,
where the interaction of threads is minimal and requires only
minimal control over thread execution.

The start() method


Q: What's the difference between a thread's start() and run()
methods?

A: The separate start() and run() methods in the Thread class


provide two ways to create threaded programs. The start()
method starts the execution of the new thread and calls the
run() method. The start() method returns immediately and the
new thread normally continues until the run() method returns.

The Thread class' run() method calls the run() method of the
Runnable type class passed to its constructor. Subclasses of
Thread should override the run() method with their own code to
execute in the second thread.

Depending on the nature of your threaded program, calling


the Thread run() method directly can give the same output as
calling via the start() method. Howevever, the code will only be
executed in a new thread if the start() method is used.

Q: Can I implement my own start() method?


A: The Thread start() method is not marked final, but should not
be overridden. This method contains the code that creates a
new executable thread and is very specialised. Your threaded
application should either pass a Runnable type to a new Thread,
or extend Thread and override the run() method.

Thread management methods


Q: Which class is the wait() method defined in?

A: The wait() method is defined in the Object class, which is the


ultimate superclass of all others. So the Thread class and any
Runnable implementation inherit this method from Object.

The wait() method is normally called on an object in a multi-


threaded program to allow other threads to run. The method
should only be called by a thread that has ownership of the
object's monitor, which usually means it is in a synchronized
method or statement block.

Q: Which class is the sleep(long) method defined in?

A: The sleep(long) method is defined as a static method of the


Thread class for two reasons. First, it is responsible for delaying
the execution of threads rather than any other objects, so
Thread is the logical host for the method. Secondly, it is static
because it suspends the currently executing thread, which is
implicitly the thread that called the method. The programmer
does not need to know which other threads are alive.

The sleep(long) method retains the synchronization locks of the


current thread, so it can have a significant effect on the
behaviour of multi-threaded applications. If the exact period of
the delay you require is not important, it may be better to use
the wait(long) method.

Q: Why are wait(), notify() and notifyAll() methods defined in the Object
class?

A: The purpose of the wait(), notify() and notifyAll() methods is to


temporarily pause and resume the execution of code in an
object. Typically the host object is not in a state where it can
proceed with a method call it has been given and the thread
of execution must literally wait for the object to return to a
ready state. A common example would be a limited pool or
store of objects where you must wait for a storage slot to be
released or an object to be returned to the pool before you
can use it.
public synchronized Object getNextObject() {

// Waiting loop
while (! objectAvailable()) {

try {

wait();
}
catch (InterruptedException e) {

// Handle exception
}
}

// No longer waiting, get the return object


Object returnObject;

// Assign the returnObject from store

// Notify state change for other waiters


notify();

return returnObject;
}

The act of waiting is associated with the Object class because


any subclass may need to wait for a ready state to occur (Java
is fundamentally a multi-threaded language). The waiting
process acts on a single thread of execution, but the wait
mechanism expects that multiple threads may be waiting for
the same object. The wait() and notify() methods are hosted by
the Object class so that the Java Virtual Machine can manage
the “wait set” of threads through the objects they are waiting
for.

Q: Why are there separate wait() and sleep() methods?

A: The static Thread.sleep(long) method maintains control of the


thread execution but delays the next action until the sleep
time expires. The wait() method gives up control over thread
execution indefinitely so that other threads can run.

Multi-threaded design questions


Q: If all methods are synchronized, is a class thread safe?

A: Even if all the methods of a class are synchronized, it may


still be vulnerable to thread safety problems if it exposes non-
final fields or its methods return mutable object references
that could be manipulated by multiple threads. Non-final fields
should be declared private and encapsulated with
synchronization. Rather than return references to internal
object fields, create an independent copy that has no relation
to the original, known as a deep copy.

A deep copy of an object duplicates the content and state of


the original object and all its constituent fields in such a way
that none of its properties refer to instances in the original at
any level.

These measures will help prevent uncontrolled access to the


internal state of objects, but you must also ensure
synchronization techniques are applied in a robust, consistent
manner that will not cause deadlock or race conditions. It is
generally better to use synchronized blocks than synchronized
methods for performance reasons. Limit the extent of
synchronized blocks and ensure they all use the same object
monitor.

Q: Do I need to use synchronized on setValue(int)?

A: It depends whether the method affects method local


variables, class static or instance variables. If only method
local variables are changed, the value is said to be confined
by the method and is not prone to threading issues.

Q: How do I create a Runnable with inheritance?

A: To introduce a Runnable type to an existing class hierarchy,


you need to create a sub-class that declares that it implements
the Runnable interface, and provide a run() method to do so.
This combination of interface and inheritance means that
runnable implementations can be very minor extensions of
existing classes, as in the example below.

Q: What is the volatile modifier for?

A: The Java language specification allows the runtime system


to keep a local copy of a variable in each thread that refers to
it. These thread-local copies of a variable act like a cache to
improve the performance of multi-threaded programs, they
avoid having to check the true master value of the variable
every time it is needed.

One consequence of this thread cache behaviour is that at the


moment of execution the value of thread-local variables may
be different from the true master value of the variable. For
variables whose value does not change frequently and would
not critically affect the behaviour of a program, thread-local
cached values are a tolerable compromise of precision for the
sake of better performance, if not they should be controlled.

You can use synchronized blocks to ensure the true master


value of a variable is used, but at the cost of excluding all
other thread access to those code blocks. The volatile modifier
ensures the integrity of a variable value without the
performance impact of full synchronization, it means that any
thread that sets or gets the variable must use the true master
value. The volatile modifier effectively disables thread-local
caching of values for specific variables.

Q: What is the SwingUtilities.invokeLater(Runnable) method for?

A: The static utility method invokeLater(Runnable) is intended to


execute a new runnable thread from a Swing application
without disturbing the normal sequence of event dispatching
from the Graphical User Interface (GUI). The method places
the Runnable object in the queue of Abstract Windowing Toolkit
(AWT) events that are due to be processed and returns
immediately. The runnable object's run() method is only called
when it reaches the front of the queue.

The deferred effect of the invokeLater(Runnable) method ensures


that any necessary updates to the user interface can occur
immediately, and the runnable work will begin as soon as
those high priority events are dealt with. The invoke later
method might be used to start work in response to a button
click that also requires a significant change to the user
interface, perhaps to restrict other activities, before the
runnable thread executes.

Q: Which has priority with a static synchronized thread?

A: A synchronized method uses what is called an intrinsic lock to


control thread execution, an object reference that is used as a
monitor for the lock. Synchronized instance methods implicitly
use their own object instance as the monitor. Only one thread
can hold the monitor object at a given moment and execute
the synchronized code.

Static synchronized methods may be executed when there is no


instance of the class to serve as a lock monitor, so must use a
different lock object. When class methods are invoked the
Java runtime system automatically creates an object of the
type Class as the context for the method to be executed. If the
class method happens to be synchronized, this Class instance is
the intrinsic lock used as the monitor object for
synchronization.

Since synchronized instance and class methods have different


monitor objects, there is no effective synchronization control
between them and no guarantee to their sequence of
execution. If a closer level of control is required, it may be
necessary to remove the synchronized modifier from the
instance method and create a synchronized block inside the
method that uses the Class instance as its monitor, as in the
example below.

Multi-threaded design patterns


Q: What is a working thread?

A: A working thread, more commonly known as a worker


thread, is the key part of a design pattern that allocates one
thread to execute one task. When the task is complete, the
thread may return to a thread pool for later use. In this
scheme a thread may execute arbitrary tasks, which are
passed in the form of a Runnable method argument, typically
execute(Runnable). The runnable tasks are usually stored in a
queue until a thread host is available to run them.

The worker thread design pattern is usually used to handle


many concurrent tasks where it is not important which
finishes first and no single task needs to be coordinated with
another. The task queue controls how many threads run
concurrently to improve the overall performance of the
system. However, a worker thread framework requires
relatively complex programming to set up, so should not be
used where simpler threading techniques can achieve similar
results.

Thread programming jargon


Q: What is a green thread?

A: A green thread refers to a mode of operation for the Java


Virtual Machine (JVM) in which all code is executed in a single
operating system thread. If a Java program has any
concurrent threads, the JVM manages multi-threading
behaviour internally rather than use additional operating
system threads.

There is a significant processing overhead for the JVM to keep


track of thread states and swap between them, so green
thread mode has been deprecated and removed from more
recent Java implementations. Current JVM implementations
make more efficient use of native operating system threads.
These days there is no case where the green thread approach
is useful except on systems where this is the only concurrency
scheme that is available for Java, on old operating systems
and hardware platforms.

Q: What are native operating system threads?

A: Native operating system threads are those provided by the


computer operating system that plays host to a Java
application, be it Windows, Mac or GNU/Linux. Operating
system threads enable computers to run many programs
simultaneously on the same Central Processing Unit (CPU)
without clashing over the use of system resources or spending
lots of time running one program at the expense of another.
Operating system thread management is usually optimised to
specific microprocessor architecture and features so that it
operates much faster than Java green thread processing.

Thread programming problems


Q: I get “incompatible return type” for my thread's getState()
method!

A: It sounds like your application was built for a Java Software


Development Kit (SDK) before Java 1.5. The Java Application
Programming Interface (API) Thread class method getState() was
introduced in version 1.5. Your thread method has the same
name but different return type. The compiler assumes your
application code is attempting to override the API method with
a different return type, which is not allowed, hence the
compilation error.

You have two main options; compile your program with a Java
SDK before version 1.5, or rename your method and adapt
any client classes to the new name.
Q: Apache Log4J has thrown a ThreadDeath error!

A: The java.lang.ThreadDeath type signals a serious Error in the


execution of a Java program and should not normally be
caught by applications, it should be left to escalate and
terminate the application. ThreadDeath is a Throwable type, so
the Apache logging package may blindly catch Throwable rather
than an Exception, which is not recommended. More likely
ThreadDeath is caught so that other asynchronous threads may
be cleaned up before logging is terminated.

Since this ThreadDeath instance is wrapped in the commons


LogConfigurationException, the root cause of the problem is most
likely that “a suitable LogFactory or Log instance cannot be
created by the corresponding factory methods”. In other
words, your logging configuration declares a type that cannot
be instantiated, possibly because of bad spelling, ultimately
because the named class is not available to the relevant
classloader.

You might also like