ECM2414 Concurrency Flashcards
Concurrency concept
To be able to perform multiple processes at the same time - including the potential interaction between them
- Multiple tasks at the same time is sometimes called parallelism
Why concurrency
- Allowing programs to interact with other systems/users
- Multi-core systems
- Systems can achieve more processes in the same time length
- Speed is key
- Productivity increases
- Consistency - real time responses
Threads
Can be treated as lightweight processes
Threads exist within a process
Processes can be considered as these big boxes. Many threads running at the same time in a process.
Why threads and not separate programs?
Shared memory space, so threads can access different segments of a program/process so said process is executed faster. A way to give a class or object the right of usage of a particular resource at a given time
The OS can run threads in parallel, how..
- Virtually on a single processor
○ On core of the system running numerous threads, not visible to users, its very fast.
○ IPC communication schedules what comes first between all the threads on the same processors - Actually on a multi-core processor
Nondeterministic processes
in sequential task management, tasks can happen one after the other
Problems: Time issues, Complexity, if the ensuing task,
memory address issues: everything relies on memory
We cannot accurately say our system is efficient as memory usage and complexity cannot be determined
Threads in Java
Can be created in 2 ways
- Using and extending the Thread class
- Using the Runnable interface
New thing to worry about - liveness
- Concerned that code performs correctly in time - i.e that good things do happen eventually
- What level of “eventually” is acceptable
current use thread lifecycle methods
Package java.lang
public class Thread implements Runnable
start
run
sleep
isAlive
interrupt
isInterrupted
interrupted
join
How do i stop a thread
Setting a flag:
Loop will exit (and thread will stop) on the next iteration after done is set to tru
Interrupting:
- As above, when isInterrupted() is called for this thread, it will stop
- Except that if the thread is sleeping/waiting will throw Interrupted Exception and immediately return from run()
Race conditions
Data synchronisation between threads can be an issue
When two threads try to access/change data at the same time it’s
known as a race condition
Synchronisation
Simply add the synchronize keyword to the methods in the class
When one thread is executing a synchronized method for an
object, all other threads that invoke synchronized methods for the
same object block suspend execution until the first thread is done with the object.
Atomic actions
In programming, atomic actions are self-contained, they cannot be stopped in the middle, they either happen or they don’t
Atomic access can help here:
- Java primitive data types: byte, short, int, long, float, double, boolean, char
- reads and writes are atomic for most primitive variables (all types except long and double)
- reads and writes are atomic for all variables declared volatile, including long and double variables
Deadlock
Thread 1 needs the resource held by thread 2
Deadlock, having a thread lock its resources, using keyword lock to shield off its resources
Starvation
Where a thread can’t gain regular access to shared resources because another thread is frequently calling the object’s methods
Livelock
A little like deadlock except that it occurs when two threads are too busy responding to one another to do work
Sleep()
used to pause the execution of the current thread for a specified time in milliseconds
yield()
a static method of Thread class and it can stop the currently executing thread and will give a chance to other waiting threads of the same priority
join()
allows one thread to wait until another thread completes its execution. In simpler words, it means it waits for the other thread to die
thread class thread management methods
sleep
yield
join
object class thread management methods
wait
notify
notifyAll
wait()
Waits for a condition to occur, must call from synchronised method/block
wait(long timeStep)
Waits for a condition for timeStep milliseconds, then returns, must call from synchronised method/block (also wait (long timeStep, int nanos))
notify()
○ Notifies a waiting thread a condition has occurred, must call from synchronised method/block (also void notifyAll();)
○ Allows thread communication
Wait vs sleep
Wait
- must occur in a block synchronised on the monitor object
- releases the monitor (lock) when called and doesn’t sacrifice the remainder of its timeslice
- will wake up if notified via a notify call
- condition controlled
Sleep
- does not need to occur in a synchronised block
- retains the monitor (lock) when called and sacrifices the remainder of its timeslice
- A sleeping thread can only be woken up by an interruption (not by notify)
- counter controlled
Thread lifecycle
new -> Runnable <-> Running -> Dead
^waiting, sleeping, blocking^
yield()
yield() causes the currently executing thread object to pause
and allow other threads to execute.
If no other threads of the same priority need to execute,
execution of this thread continues
Identifies the current thread as doing something not particularly
important
Specify when a specific thread should yield for another
Join()
Simple function allows one thread to wait for the completion of
another.
t.join()
Like sleep, join responds to an interrupt by exiting with an
InterruptedException
Explicit locking: the lock interface
In synchronized, the lock exists but isnt seen
It is possible to create move and destroy locks through the lock object
Using the lock interface we can manage locks and:
- Two or more objects can share a lock
- One object can have multiple locks
Atomic variables
- Even a simple increment consists of get, change and set operations
- Java uses java.util.concurrent.atomic to provide variables that support atomic operations on single variables
- Atomic variables contain methods to deal with this, supporting atomic operations ensureing that increments, decrements, or reads happen as a single uninterruptable operation
- AtomicInteger, AtomicLong, AtomicBoolean
Atomicity ensures the data is fresh
atomic access functions
set()
get()
getAndSet()
compareAndSet()
weakCompareAndSet()
atomicInteger and atomicLong also implement:
- incrementAndGet()
- decrementAndGet()
- getAndIncrement()
○ XAndGet atomically performs X and returns updated value
○ getAndX atomically performs X and returns original value
- getAndDecrement()
- addAndGet()
- getAndAdd()
Volatile variables
Declaring a variable volatile tells the compiler not to optimise access and forces the next read to see the last write
Waits for data to be thread before continuing
Publishing & Escape
Publishing an object is when you make it available outside its current scope
- e.g. storing a reference to it where other code can find it, it may be a non-private attribute
By default, we shouldn’t publish an object unless we have to
- If we do, we may need to confirm the thread-safe nature of the publishing
An object published when it should not have been is said to have escaped (e.g. accessing an initialised state variable)
Any object that is reachable from a published object by some chain of non-private field references has also been published
Thread confinement
One of the simplest ways to ensure thread-safety
If the data doesn’t need to be shared, confine it to a single thread
If data is only used by a single thread then it is said to be confined
Thread confinement is an element of the program’s design
Lamdba Expression
Java 8.0 introduced Lambda Expressions
- Introduced aspects of functional programming to the language for the first time
Single largest upgrade to the language ever (and this includes generics that we’ll cover later in the module)
- Mark Reinhold, Chief Architect: Java Platform Group, Oracle
Java 8.0 was released in 2014 so should be available across machines
A lambda expression is essentially a block of code that you can pass around between objects (previously you could only pass objects or primitives between objects)
lambda expression syntax and distinctions
Syntax is (arguments) -> {body}
- Can have 0 or more arguments
- Argument type can be declared or inferred
- With only a single inferred argument, no parentheses are needed
- A body with a single expression does not require curly brackets