Concurrency in Java

24
Java & Concurrency Lakshmi Narasimhan

description

A set of slides on the basics of concurrency touching upon Java's support for multi-threaded programming, do's and dont's, common approaches to developing concurrent applications and evolution of APIs in Java that support effective multi-threaded programming

Transcript of Concurrency in Java

Page 1: Concurrency in Java

Java & Concurrency

Lakshmi Narasimhan

Page 2: Concurrency in Java

2

Agenda

United at birth

Why more relevant now

Concurrency over the years

Basics & Myths

Concurrency Patterns

Deep-dive

There's more than one way to solve it!!

Common gotchas

Q&A

Page 3: Concurrency in Java

3

Java & Concurrency : United at birth

● In-built into the language ● Not an after thought

● Support for threads from Day 1

● Everything is a monitor

● Simplicity over complexity● Multiple inheritance● Operator overloading

● Choice of languages● Scala, Clojure

Page 4: Concurrency in Java

4

Why is it more relevant now

• H/W & S/W trends

– No longer privilege of few

– Scaling accentuates Vertical and horizontal scaling mean more complexity

– Distributed caches, faster I/O

– Weak Cache coherence

• Application requirements

– Impunity of slow system lifted

– Elasticity is the mantra

– The weakest link draws the whole system down

– Bottlenecks can be really really costly

Page 5: Concurrency in Java

5

Concurrency over the years

Java VersionJava Version FeaturesFeaturesJDK 1.0 ●Threads

●“synchronized” keyword●HashTable(thread-safe but synchronized classes)

JDK 1.2 ●Collections framework(updated)●un-synchronized classes bound by synchronized accessors●eg: Collections.synchronizedMap()●Use when you need sync

JDK 1.5 ● concurrency package JSR166 java.util.concurrent

JDK 7 ● Updated java.util.concurrent package(JSR166y)Fork-Join and Executor Framework

JDK 8 ● Modularity● Lamda

Page 6: Concurrency in Java

6

Concurrency : BasicsThree elements of a concurrent Application Atomicity

Certain pieces of an application must all be executed as one unit● Visibility

Changes that you make to a value to be visible precisely when you intend them to be

● Synchronization

Concurrent access to shared variables should be guarded

Terms you will come across

● JMM – The specification that guarantees how the JVM should work

● Monitor – Intrinsic lock (Every object has a monitor associated with it)

● Race condition – An operation on shared resources whose outcome may be in-deterministic

Page 7: Concurrency in Java

7

Concurrency : Myths

● The more the threads, faster my application is

• A bigger system means faster execution

• Processors/compilers can optimize my code for parallelism

• Locks make the program go slow

• Re-factoring is easy

• Writing concurrent application is a black-art

Page 8: Concurrency in Java

8

Common concurrency patternsDynamic Exclusion Through Implicit Locks• a.k.a “synchronized”

• Lock obtained if method is declared synchronized

• Watch out for fine/coarse grained locks.

• Dos/Dont's:

– Avoid CPU/IO intensive operations inside “synchronized” block.

– “synchronize” on a code block and not method (if appropriate)

• Remember that JIT can re-order execution

Page 9: Concurrency in Java

9

Common concurrency patterns

Structural Exclusion Through Confinement

• Options:– Thread confinement : Access object from a single thread using

thread-per-session approach

– Instance confinement : Use encapsulation techniques to restrict access to object state from multiple threads

– Method confinement : Do not allow an object to escape from method by referencing it through local variables

• Do's/Dont's:

– Confinement cannot be relied on unless a design is leak proof

– Combine confinement with appropriate locking discipline

– Use ThreadLocal variables to maintain Thread Confinement

Page 10: Concurrency in Java

10

Common concurrency patternsImmutability

• Object state cannot change after construction

• Are automatically thread-safe

• Immutability is guranteed only when :

– All fields are declared final

– Object reference fields must not allow modifications anywhere in the object graph reachable from the fields after construction

– The class should be declared final (to prevent a subclass from subverting these rules)

• Immutable objects eliminate a bunch of issues around concurrency. Use whenever you can.

• Have “failure atomicity” - upon an exception, state is never undesirable or indeterministic.

"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot "Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible." - Joshua Blochbe made immutable, limit its mutability as much as possible." - Joshua Bloch

Page 11: Concurrency in Java

11

Common concurrency patterns

Co-operation

• Wait-notify mechanisms

• One thread creates a condition and another one waits for it

• All threads are treated the same - when multiple threads are waiting, no guarantee on which one would wake up

• Missed or early notifications

• Do's/Dont's:– Use notifyAll() instead of notify()

– Wait() in a while loop

– Call wait() and notify() inside synchronized block

Page 12: Concurrency in Java

12

Deep Dive• JSR166 - “java.util.concurrent” packages

• Introduced in JDK 5

• Motivation

– Creating APIs for commonly used functionality

– Application/scenario agnostic

– “volatile” guaranteed visibility but not atomicity

– Synchronization is expensive (and can cause dead-lock)

● Atomic Variables, nanosecond timing, Condition variables, Lock classes, tryLock, Queues, Barriers, Executors.....

Page 13: Concurrency in Java

13

Deep Dive – Atomic Classes• java.util.concurrent.atomic.Atomic* classes

● Provides a worthy substitute for “volatile” and “synchronized”

● Available on Integer, Long, Boolean, Object Ref, Arrays

● CompareAndSet(), incrementAndGet() etc guarantee atomicity

Page 14: Concurrency in Java

14

Deep Dive : LocksReentrantLock

“synchronization” on steroids

Supports Lock state, non-blocking tryLock() and interruptible locking

Throughput can be higher by order of magnitudes

Can be extended to set “fairness” and “Condition”

Use ONLY and ONLY if “synchronized” will not solve your problems

If your Application needs timed-locks, interruptible locks, multiple condition locks

Page 15: Concurrency in Java

15

Deep Dive : Executor Framework● Implemented via java.util.concurrent.ExecutorService

● Provides flexible thread pool implementation

● Producer-consumer pattern

– Producer : Creates work

– Consumer : Executes the work

● Consider newCachedThreadPool if you don't want to bound no. of threads

Page 16: Concurrency in Java

16

Deep Dive : Executor Framework● Remember to shut it down

● Asynchronous execution may hide hidden tasks

Page 17: Concurrency in Java

17

Deep Dive: Fork Join Framework“Framework for supporting a style of programming in which problems are solved by recursively splitting them in to sub tasks that are solved in parallel, waiting for them to complete and then composing results”

● Introduced through JSR166y and part of Java 7

● Introduces Parallel-Array (PA) concept to Java (simlar to Map-Reduce?)

● Extends the executor framework for Recursive style problems

●Makes use of work stealing algorithm

●Transparent Parallelism requiring no tuning (almost!)

●Suited for MMP Architectures.

● Number of sub tasks can be altered at run-time

“Fork” Starts a new parallel fork/join subtask

“Join” causes current task not to proceed until the forked task is complete

This can happen recursively till tasks are smaller enough to be solved sequentially

Components of a FJ framework

● The guy who does the work (business logic)

● The guy who tells how the work can be split

● The guy who coordinates it all (FJ)

Page 18: Concurrency in Java

18

There's more than one way to solve it● There's always more than one way to solve the problem

● Know the pros/cons of each approach

● Example :

Not Thread Safe

Page 19: Concurrency in Java

19

Option 1 : Using “volatile” keyword

Pros:

● Simple, easy to write and understand

● Would solve most of the requirement

Cons:

● Thread looping

● No option to know/set priority of waiting threads

There's more than one way to solve it

Page 20: Concurrency in Java

20

Option 2 : Using “AtomicBoolean”

Pros:

● Fairly straight-forward

● “tryLock()” can prevent costly thread spins

● Flexibility to set Condition and “fairness” of waiting threads

Cons:

● Slight over-head if you need primitive data locking

There's more than one way to solve it

Page 21: Concurrency in Java

21

Option 3 : Using “synchronized”

Pros:

● Locks are intrinsic and so no need to release them explicitly

Cons

● Code is a lot more verbose

● Empty thread looping

There's more than one way to solve it

Page 22: Concurrency in Java

22

Common concurrency mistakes● synchronization

– Fine/coarse grained synchronization

– Synchronizing just data

– Validating data integrity at one level

– Synchronizing on “null”

– Changing synchronizing object instance

– Synchronizing on string literals

– Writing with synchronization but reading w/o it

– Volatile array -

• “valarr” is a volatile reference to an array, but array elements are not

Page 23: Concurrency in Java

23

Common concurrency mistakes● Volatile will work only when

– write to variable does not depend on current value

– Write does not depend on any other non-atomic operation

● CachedThreadPool is un-bound – You may run out of resources sooner than you thought

● The list never ends.....

● Recommend go through “Java Platform Concurrency Gotchas” - Alex Miller

Page 24: Concurrency in Java

24

Re-cap

Relevance of concurrency

Basics & Myths

Concurrency Patterns

Deep-dive

There's more than one way to solve it!!

Common gotchas

Q&A