Concurrency N

You might also like

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 3

Chapter 30 in Daniel liang and chapter 1-5 and 10 in the other

Thread
process
Implement
Competition in threaded environment
Locks and problems with dynamic and simple lock
Dining philosophers
Synchronizers - semaphore, latches, monitors

An atomic operation is one


that is atomic with respect to all operations, including itself, that operate
on the same state.

We refer collectively to check-then-act and read-modify-write sequences as compound


actions: sequences of operations that must be executed atomically in order
to remain thread-safe.

If synchronization is used to
coordinate access to a variable, it is needed everywhere that variable is accessed.
Further, when using locks to coordinate access to a variable, the same lock must be
used wherever that variable is accessed.

Stateless objects are always thread-safe. Therefore, servlets can be implemented to


be thread-sage with much less burden, unless the servlets want to remember things
from one request to the other and therefore require a state.

safety: nothing bad ever happens


liveness: something good eventually happens
performance: something good happens quickly

ForkJoinPool takes advantage of multiple processors by forking tasks into


asynchronous tasks and then joining them together to return the result of their
computations.
The same way we create Thread Pools is the same way we create ForkJoinPools, only
that executors execute tasks, while ForkJoinPools invoke ForkJoinTasks.

Fail-Fast systems abort operation as-fast-as-possible exposing failures immediately


and stopping the whole operation. Whereas, Fail-Safe systems don’t abort an
operation in the case of a failure. Such systems try to avoid raising failures as
much as possible.

deadlock is easily avoided by using a simple technique called "resource ordering".

Semaphore: an object that controls the access to a common resource.

Locks are explicit:


calling condition methods without owning the lock, an IllegalMonitorStateException
will be thrown.

Monitors are implicit:


calling the monitor methods from a block of code that isn't synchronized to the
monitor will result in an IllegalMonitorStateException being thrown.

volatile: the variable is volatile and should not be cache. Since it ensures
visibility which applies only to read operations, it will naturally only be usable
on field declarations.
Example: private volatile String notes;
Synchronized: synchronize access to this block of code. It ensures both visibility
and atomicity (or mutual exclusion) so it can be used on blocks of code (also
methods) that have the ability to write or read data, and not on the data itself.
It also performs the visibility function by making sure all the variables declared
inside the block of code is read directly from the main memory at all times instead
of the cache.
Example 1:
public synchronized void takeNotes() {

Example 2:
public void takeNotes() {
sychronized (lock) {

}
}

note: instead of using synchronized keyword to wrap only read operations on a


particular field variable, just simply use the volatile keyword to reduce overhead
in your java application.

Question: what if we want to wrap read and write operations on just a single field
variable without using synchronized?
Answer: Atomic variables

Atomic operaion: the smallest operation; an operation that cannot be broken down;
it is also an operation that is performed either entirely or not at all. This means
once a thread is already performing that operation, all others must wait (not at
all) until the thread is through (entirely). If it has to be performed entirely or
not at all, then there is no possibility of there being race conditions whereby
data integrity is lost or the accuracy is compromised because of the existence of
multiple threads performing different stages of the operation interlacingly. An
operation to increment i has to first get the value of i(read operation), increment
it, and update it accordingly(write operation). If after the operation performs the
read operation, another variable performs a write operation changing the variable,
then the integrity of the final result will be compromized.

synchronized keyword basically makes a block of code atomic, as long as none of the
operations performed within the synchronized block is performed elsewhere. All the
operations will either be performed at once and to completion or not at all, and
there is no possibiltity of interlacing errors.

Turning the variable into an atomic variable can also help with this. The classes
contain atomic methods that perform common non-atomic operations, such as
getAndIncrement(). This makes it such that as long as you define your atomic
variable, you won't have to create your own atomic block of code and then try not
to use the same operations elsewhere in a non-atomic way. Instead you just use the
provided atomicized operations to keep your application thread safe.
There are different classes of atomic variables containing atomicized operations
that are commonly required for certain types of variables. For example, the
AtomicInteger class contains the getAndIncrement() atomic method that performs the
common integer operation, get and increment. Others are AtomicLong, AtomicBoolean,
AtomicReference.

The get and set variables also allow writing and reading of data directly to memory
instead of cache.
Monitors: In concurrent programming, a monitor is an object intended to be used
safely by more than one thread.

You might also like