48
Concurrency in Object Oriented Programs 1 Object-Oriented Software Development COMP4001 CSE UNSW Sydney Lecturer: John Potter

Concurrency in Object Oriented Programs 1cs4001/12s1/lect/1.conc.pdf · Reference books ! Java Concurrency in Practice. by Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer,

Embed Size (px)

Citation preview

Concurrency in Object

Oriented Programs 1

Object-Oriented Software Development

COMP4001 CSE UNSW Sydney

Lecturer: John Potter

Outline

§  Concurrency: the Future of Computing §  Java Concurrency §  Thread Safety §  Synchronization

COMP4001 CSE UNSW Sydney 2

Why Don’t We Have 20GHz CPU?

Intel CPU Introductions COMP4001 CSE UNSW Sydney

3

What’s Happening? §  Traditional processor architecture has reached

hard limits §  The clock speed race is over (at least for now)

§  Multicore processors become mainstream §  Most new computers are currently dual/quad cores §  Sun’s Niagara 2, 8-core and run 64 threads §  Tilera’s TILE64, 64-core §  Teraflops Research Chip (Polaris), a 3.16 GHz, 80-

core processor prototype §  Myths and Realities: 2 x 3GHz = 6 GHz?

COMP4001 CSE UNSW Sydney 4

Where Do We Go from Here? §  The transition to multicore processors is inevitable

§  a fundamental shift in computer design and software development

§  The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software, by Herb Sutter §  http://www.gotw.ca/publications/concurrency-ddj.htm

§  Until now: increasing clock speeds §  All programs (even sequential programs) run faster

§  From now: increasing number of cores §  Only concurrent programs will run faster! §  Concurrency is the next major revolution in how we

write software COMP4001 CSE UNSW Sydney

5

Benefits of Concurrency §  Exploit multicore processors

§  Programs need to use more cores to maximize performance

§  Hide latency from slow I/O (disk, network, etc.) §  CPUs are much faster than I/O §  Works even with single core

§  Keep GUIs more responsive §  Event dispatch thread (EDT) in Java AWT and

Swing

COMP4001 CSE UNSW Sydney 6

Threads vs Processes §  OS Processes

§  heavyweight §  separate address space §  interact with simple read/write streams §  synchronization is simpler

§  Threads §  lightweight §  shared memory space §  directly share variables (more efficient) §  synchronization is more difficult

§  Most modern operating systems treat threads as the basic unit of scheduling

COMP4001 CSE UNSW Sydney 7

Concurrency is Hard §  Automatic approaches are not sufficient

§  Instruction level parallelism is limited

§  Explicit concurrency is needed! §  Allow programmers to take full advantage of their

program-specific knowledge §  Concurrent programming can be difficult

§  Programmers must be aware of thread safety issues §  Concurrency programming introduce new kinds

of bugs §  Concurrency bugs are counterintuitive §  Old bugs become worse – harder to detect

COMP4001 CSE UNSW Sydney 8

Concurrency is Hard §  Concurrency bugs – the memory bugs of the

21st century

§  Most languages provide support for explicit multithread programming

§  However, no programming model or language construct invented yet to make the problem go away! §  still an active research area

COMP4001 CSE UNSW Sydney 9

Outline

§  Concurrency: the Future of Computing §  Java Concurrency §  Thread Safety §  Synchronization

COMP4001 CSE UNSW Sydney 10

Reading Materials

§  Java Concurrency Tutorial §  http://docs.oracle.com/javase/tutorial/essential/concurrency/

§  Reference books §  Java Concurrency in Practice. by Brian Goetz, Tim

Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, and Doug Lea. Addison-Wesley. §  See http://jcip.net/

§  Concurrent Programming in Java: Design Principles and Patterns, Second Edition, by Doug Lea. Addison-Wesley.

COMP4001 CSE UNSW Sydney 11

Java Threads §  Java provides direct support for multi-threaded

applications §  JVM provides a native multi-threaded model §  JVM keeps track of all the threads §  JVM schedules threads to get CPU time

§  Each Java thread has its own stack §  executes statements and make calls

§  Java threads share objects in the heap §  Threads communicate via objects on the heap §  This is a shared memory model

COMP4001 CSE UNSW Sydney 12

Java Threads §  Threads are regular Java objects §  A Thread object represents a thread of control

in the JVM §  with thread data (e.g. priority) §  methods to control thread execution

§  Programmers can send messages (i.e. make method calls) to control the Thread object §  JVM interprets messages §  Executes the appropriate operations on the

underlying thread of control in the JVM

COMP4001 CSE UNSW Sydney 13

The main Thread §  A Java program begins with a thread executing

main() §  In a sequential Java program, the main thread

executes the whole program §  The program exits when the main thread reaches

the end of main() §  The JVM will often run extra threads outside of

programmer control e.g. garbage collection §  In a concurrent Java program, new threads are

created and run concurrently §  The program may keep running on the other threads

even if the main thread exits COMP4001 CSE UNSW Sydney

14

The Current Running Thread §  There is always a current running thread at any

time during computation §  Thread.currentThread()

§  A static method which returns a reference to the current thread of control

Thread current = Thread.currentThread();

§  current is the Thread object that represents the current thread of control

COMP4001 CSE UNSW Sydney 15

Thread Names §  getName() on a Thread object

§  By default, the method returns something like Thread-0, Thread-1, Thread-2, ... for each thread created by the program

§  A convenient method for debugging.

§  Alternatively, the Thread constructor can take a String that is used for the name.

COMP4001 CSE UNSW Sydney 16

Thread Creation in Java §  Construct runtime Thread objects directly

§  subclassing with the Thread class, or §  delegation with the Runnable interface

§  Thread initialisation is done via new §  not the same as thread execution

§  Threads must be started by explicitly calling start() §  after it has been constructed §  thread cannot be started more than once

COMP4001 CSE UNSW Sydney 17

Approach 1: The Thread Class 1.  Define a subclass of Thread 2.  Override the run() method 3.  Construct your own Thread object 4.  Start the thread separately from another

thread by calling start() §  This will cause the JVM to start-up a new thread

and execute the run() method of the thread §  The start method will return and the calling thread

continues and run concurrently with the new thread

COMP4001 CSE UNSW Sydney 18

Thread Class Example public class HelloThread extends Thread {

public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { helloThread = new HelloThread(); helloThread.start(); }

}

COMP4001 CSE UNSW Sydney 19

Approach 2: The Runnable Interface 1.  Implement the Runnable interface in a

separate (non-Thread) class 2.  Implement the run() method 3.  Construct the Runnable and hand it to a new

Thread object 4.  Then start this thread at your leisure by calling

start()

§  Delegation with Runnable interface is preferred §  subclassing Thread implies that we cannot inherit

other code COMP4001 CSE UNSW Sydney

20

Runnable Interface Example public class HelloRunnable implements Runnable {

public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { helloThread = new Thread(new HelloRunnable()); helloThread.start(); }

}

COMP4001 CSE UNSW Sydney 21

Self-starting Thread Example §  We can make threads self-starting ...

public class SelfStarter implements Runnable { public SelfStarter() { (new Thread(this)).start(); } public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { new SelfStarter(); } }

COMP4001 CSE UNSW Sydney 22

Thread Communication §  Threads communicate via shared objects §  Access to these objects is initiated when the

thread is constructed §  The creating thread passes a reference to one or

more objects to a created thread §  via constructor of the Runnable object

§  Both threads may then communicate via those objects §  and other objects they both gain access to

§  Runnables are directly shareable §  then the Runnable should be made thread-safe

COMP4001 CSE UNSW Sydney 23

Outline

§  Concurrency: the Future of Computing §  Java Concurrency §  Thread Safety §  Synchronization

COMP4001 CSE UNSW Sydney 24

Thread Safety

public class UnsafeCount { private int value; /** Counts the number of calls. */ public void count() { value++; }

} §  Is the result of counting correct?

COMP4001 CSE UNSW Sydney 25

Thread Safety §  Two threads could call count(), but sometimes

only one call is counted, WHY?

COMP4001 CSE UNSW Sydney 26

Thread Safety §  Two threads could call count(), but sometimes

only one call is counted, WHY?

§  value++ involves three separate operations: §  read the integer stored in value §  add one to the integer §  write the result to value

COMP4001 CSE UNSW Sydney 27

Thread Safety §  Two threads could call count(), but sometimes

only one call is counted, WHY?

§  value++ involves three separate operations:

COMP4001 CSE UNSW Sydney 28

Race Conditions

Definition: A race condition occurs when the same memory location may be accessed by different threads simultaneously, and at least one access is a write.

§  Also called data races §  This occurs when different threads access the

same data field of an object (or class) §  In Java, local variables are not shared across

threads, so race conditions never occur for locals COMP4001 CSE UNSW Sydney

29

Race Conditions §  The correctness of a program relies on ‘luck’

§  i.e. how threads interleave their execution

§  Locating concurrency bugs is hard §  They exhibit themselves sporadically

§  Many of the bugs seen in software products are concurrency bugs §  They were not tracked down during testing

§  “… most Java programs are so rife with concurrency bugs that they work only ‘by accident’.” – Brian Goetz et al., Java Concurrency in Practice, Addison-Wesley

COMP4001 CSE UNSW Sydney 30

Questions on Thread Safety §  How can we ensure that objects can be safely

used by more than one thread? §  What does safely mean? §  Should we allow arbitrary concurrent access?

§  How can we restrict access?

§  Lead to concurrency control §  synchronisation and locking strategies

§  With concurrent updates §  who sees which changes, when? §  constraints on ordering defined by the Java memory

model JMM §  JMM specifies that fields of objects shared by threads may

be read and written independently §  unless specific synchronisation techniques are used COMP4001 CSE UNSW Sydney

31

Achieving Thread Safety §  Immutability

§  If objects are immutable then arbitrary concurrent access is safe

§  Don’t share mutable objects across threads

§  ThreadLocal objects

§  Synchronization §  dynamically controlling access of different threads to

shared objects

COMP4001 CSE UNSW Sydney 32

Outline

§  Concurrency: the Future of Computing §  Java Concurrency §  Thread Safety §  Synchronization

COMP4001 CSE UNSW Sydney 33

Critical Section §  A section of code that manipulates shared

memory, and so must NOT be run by multiple threads at the same time.

public class UnsafeCount { private int value; /** Counts the number of calls. */ public void count() { value++; }

}

COMP4001 CSE UNSW Sydney 34

Mutual Exclusion – “mutex” §  Scheduling threads so that only one thread at a

time executes a critical section of code §  Essentially, keeping the threads from

interfering with each other §  Avoid conflicts on shared memory between

threads

§  Java ensures mutual exclusion with intrinsic locks

COMP4001 CSE UNSW Sydney 35

Intrinsic Locks §  Every object has an intrinsic lock or monitor

associated with it

§  A method may be annotated with a key word ‘synchronized’ §  Synchronized instance methods acquire the lock for

the receiver of the call (the self object this) §  Synchronized static methods acquire the lock of the

Class object for the defining class §  There is one such object per class in the Java runtime

COMP4001 CSE UNSW Sydney 36

Synchronized Methods §  A synchronized method respects the lock of the

receiver object §  Before a thread executes a synchronized

method, it first obtains the lock of the receiver §  The lock is released when the method exits

§  If the lock is already held by another thread, it will block §  until the lock is released, i.e. the thread with the lock

exits the method §  Mutual exclusion is ensured in this way

COMP4001 CSE UNSW Sydney 37

Synchronized Methods public class SafeCount {

private int value; /** Counts the number of calls. */ synchronized public void count() { value++; }

}

§  Methods may be declared synchronized §  No two calls by different threads on the same object

may be executed simultaneously §  Calls may be blocked

§  Exit of a synchronized method happens before (officially) subsequent synchronized calls

COMP4001 CSE UNSW Sydney 38

Synchronized Methods and Class Extension

§  Synchronized declaration is not inherited by subclasses §  when a class is extended, must re-declare all

synchronized behaviours as necessary §  in effect, achieve little code reuse for concurrent

objects §  This general principle is called the inheritance

anomaly (ref Matsuoka) for concurrent OO §  If a method is not synchronized, it will ignore

the lock and just go ahead.

COMP4001 CSE UNSW Sydney 39

Reentrant Lock §  A thread can acquire the same lock multiple

times §  Current Thread ID is checked against the thread

holding the lock §  if the ID matches (i.e. a re-entrant call), a new entry

is allowed §  The object will stay locked until all entries have

exited

§  A thread never blocks waiting for itself

COMP4001 CSE UNSW Sydney 40

Single-Threaded Objects §  A simple idiom for making objects thread-safe

§  Declare all public methods synchronized §  This part is easy

§  And prohibit other threads accessing fields and unsafe methods §  Easier said than done!

§  use of private access modifier restricts class level access and not object or thread level access

§  Needs good program discipline

§  This ensures that at most one thread can be using the object at a time

COMP4001 CSE UNSW Sydney 41

Synchronization Wrappers §  An aside:

§  Review Decorator design pattern §  Extend base object with decorators (or wrappers)

§  Decorators implement same interface §  Delegate most behaviour to base object

§  Can write synchronization decorators to do so §  java.util.Collections provides static factory methods

to construct synchronization wrappers for standard collections

List<E> list = Collections.synchronizedList (new ArrayList<E>()); Set<E> set = Collections.synchronizedSet (new HashSet<E> ()); Map<K,V> map = Collections.synchronizedMap (new HashMap<K,V> ());

COMP4001 CSE UNSW Sydney 42

What about Constructors?

§  Constructors can NOT be synchronized

§  Programmer discipline required (again)!

§  Thread-safe as long as the constructor does not leak references to the new object to other threads during constructor execution

COMP4001 CSE UNSW Sydney 43

Synchronized Blocks §  Any block of code can be synchronized

§  A variant of synchronized methods §  Acquire and release lock for a specified object

public void addName(String name) { synchronized(this) { lastName = name; nameCount++; } nameList.add(name); }

COMP4001 CSE UNSW Sydney 44

Synchronized Block vs Method §  In general its good style to factor out

synchronized blocks into synchronized methods §  If need be, by refactoring methods so that critical

sections needing synchronization appear as separate methods

public void addName(String name) { setName(name);

nameList.add(name); } synchronized protected void setName(String name) { lastName = name; nameCount++; } COMP4001 CSE UNSW Sydney

45

Finer Grain Synchronisation §  Synchronization blocks allow finer grain of control

§  Gives more flexibility (but use may still indicate poor class design

§  Example: lock splitting public class MsLunch { private long c1 = 0; private long c2 = 0; private Object lock1 = new Object(); private Object lock2 = new Object(); public void inc1() {

synchronized(lock1) { c1++; } } public void inc2() { synchronized(lock2) { c2++; } } }

COMP4001 CSE UNSW Sydney 46

Finer Grain Synchronisation §  Exercise:

§  What are the possible interleavings of calls on inc1 and inc2 by different threads? §  describe this by thinking of each call has being

bracketed by two events: §  call start and call end

§  How is this possible behaviour different from having both inc1 and inc2 declared to be synchronized methods?

§  Why are lock1 and lock2 declared to be of type Object?

COMP4001 CSE UNSW Sydney 47

Homework §  Brush up on your Java skills if need be

§  Recommended IDE is Eclipse (Classic is enough) §  See Scala web-site for recommended version for use with

scala plugin

§  Start reading the online Java Concurrency Tutorial §  Some parts will be covered in next lecture §  Decide whether you need to acquire a reference

book: first choice is Java Concurrency in Practice §  Try to compile and run the examples from the

Tutorial §  add print statements to observe interleaving of

thread executions

COMP4001 CSE UNSW Sydney 48