DZone, Inc.
|
www.dzone.com
By Alex Miller
ABOUT JAVA CONCURRENCY
Core Java Concurrency www.dzone.com Get More Refcardz! Visit refcardz.com
#61
Core Java Concurrency
From its creation, Java has supported key concurrency
concepts such as threads and locks. This guide helps
Java developers working with multi-threaded programs
to understand the core concurrency concepts and how
to apply them. Topics covered in this guide include built-
in Java language features like Thread,
synchronized, and
volatile, as well as new constructs added in JavaSE 5 such as
Locks, Atomics, concurrent collections, thread coordination
abstraction, and Executors. Using these building blocks,
developers can build highly concurrent and thread-safe Java
applications.
CONCEPTS
This section describes key Java Concurrency concepts that are
used throughout this DZone Refcard.
Table 1: Java Concurrency Concepts
Concept Description
Java Memory
Model
The Java Memory Model (JMM) was defined in Java SE 5 (JSR 133) and
specifies the guarantees a JVM implementation must provide to a Java
programmer when writing concurrent code. The JMM is defined in terms
of actions like reading and writing fields, and synchronizing on a monitor.
These actions form an ordering (called the “happens-before” ordering)
that can be used to reason about when a thread sees the result of another
thread’s actions, what constitutes a properly synchronized program, how to
make fields immutable, and more.
Monitor
In Java, every object contains a “monitor” that can be used to provide
mutual exlusion access to critical sections of code. The critical section is
specified by marking a method or code block as synchronized. Only
one thread at a time is allowed to execute any critical section of code for a
particular monitor. When a thread reaches this section of code, it will wait
indefinitely for the monitor to be released if another thread holds it. In
addition to mutual exlusion, the monitor allows cooperation through the
wait and notify operations.
Atomic field
assignment
Assigning a value to a field is an atomic action for all types except doubles
and longs. Doubles and longs are allowed to be updated as two separate
operations by a JVM implementation so another thread might theoretically
see a partial update. To protect updates of shared doubles and longs,
mark the field as a volatile or modify it in a synchronized block.
Race condition
A race condition occurs when more than one thread is performing a series
of actions on shared resources and several possible outcomes can exist
based on the order of the actions from each thread are performed.
Data race
A data race specifically refers to accessing a shared non-nal
non-volatile field from more than one thread without proper
synchronization. The Java Memory Model makes no guarantees about
the behavior of unsynchronized access to shared fields. Data races are
likely to cause unpredictable behavior that varies between architectures
and machines.
Safe publication
It is unsafe to publish a reference to an object before construction of the
object is complete. One way that the this reference can escape is by
registering a listener with a callback during construction. Another common
scenario is starting a Thread from the constructor. In both cases, the
partially constructed object is visible to other threads.
Final fields
Final fields must be set to an explicit value by the end of object
construction or the compiler will emit an error. Once set, final field values
cannot be changed. Marking an object reference field as final does
not prevent objects referenced from that field from changing later. For
example, a final ArrayList field cannot be changed to a different
ArrayList, but objects may be added or removed on the list instance.
Final fields,
continued
At the end of construction, an object undergoes “final field freeze”, which
guarantees that if the object is safely published, all threads will see the
values set during construction even in the absence of synchronization.
Final field freeze includes not just the final fields in the object but also all
objects reachable from those final fields.
Immutable
objects
Final field semantics can be leveraged to create thread-safe immutable
objects that can be shared and read without synchronization. To make an
immutable object you should guarantee that:
• The object is safely published (the this reference does not escape
during construction)
• All elds are declared nal
• Object reference elds must not allow modications anywhere in the
object graph reachable from the fields after construction.
• The class should be declared nal (to prevent a subclass from
subverting these rules)
PROTECTING SHARED DATA
Writing thread-safe Java programs requires a developer to
use proper locking when modifying shared data. Locking
establishes the orderings needed to satisfy the Java Memory
Model and guarantee the visibility of changes to other threads.
Hot
Tip
Data changed outside synchronization has NO
specified semantics under the Java Memory Model!
The JVM is free to reorder instructions and limit
visibility in ways that are likely to be surprising to a
developer.
Synchronized
Every object instance has a monitor that can be locked by
one thread at a time. The
synchronized keyword can be
specified on a method or in block form to lock the monitor.
Modifying a field while synchronized on an object guarantees
that subsequent reads from any other thread synchronized on
the same object will see the updated value. It is important to
note that writes outside synchronization or synchronized on a
different object than the read are not necessarily ever visible to
other threads.
CONTENTS INCLUDE:
n
About Java Concurrency
n
Concepts
n
Protecting Shared Data
n
Concurrent Collections
n
Threads
n
Threads Coordination and more...
n
Authoritative content
n
Designed for developers
n
Written by top experts
n
Latest tools & technologies
n
Hot tips & examples
n
Bonus content online
n
New issue every 1-2 weeks
Subscribe Now for FREE!
Refcardz.com
Get More Refcardz
(
They’re free!
)