Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of...

37
Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park
  • date post

    21-Dec-2015
  • Category

    Documents

  • view

    217
  • download

    0

Transcript of Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of...

Page 1: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Synchronization in Java

Nelson Padua-Perez

Bill Pugh

Department of Computer Science

University of Maryland, College Park

Page 2: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Synchronization Overview

Unsufficient atomicity

Data races

Locks

Deadlock

Wait / Notify

Page 3: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Unsufficient atomicity

Very frequently, you will want a sequence of actions to be performed atomically or indivisibly

not interrupted or disturbed by actions by any other thread

x++ isn’t an atomic operationit is a read followed by a write

Can be a intermittent errordepends on exact interleaving

Page 4: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Insuffient Atomicity Example

public class InsuffientAtomicity implements Runnable { static int x = 0; public void run() { int tmp = x;

x = tmp+1; } public static void main(String[] args) { for (int i = 0; i < 3; i++) new Thread(new InsuffientAtomicity ()).start(); System.out.println(x); // may not be 3 }}

Page 5: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Data Race

DefinitionConcurrent accesses to same shared variable, where at least one access is a write

variable isn’t volatile

Can expose all sorts of really weird stuff the compiler and processor are doing to improve performance

Page 6: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Quiz Time

x = y = 0

x = 1

j = y

Thread 1

y = 1

i = x

Thread 2

Can this result in i = 0 and j = 0?

start threads

Page 7: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Answer: Yes!

x = y = 0

x = 1

j = y

Thread 1

y = 1

i = x

Thread 2

How can i = 0 and j = 0?

start threads

Page 8: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

How Can This Happen?

Compiler can reorder statementsOr keep values in registers

Processor can reorder them

On multi-processor, values not synchronized to global memory

The memory model is designed to allow aggressive optimization

including optimizations no one has implemented yet

Good for performancebad for your intuition about insufficiently synchronized code

Page 9: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Synchronization

UsesMarks when a block of code must not be interleaved with code executed by another thread

Marks when information can/must flow between threads

NotesIncurs a small amount of runtime overhead

if only used where you might need to communicate between threads, not significant

used everywhere, can add up

Page 10: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Lock

DefinitionEntity can be held by only one thread at a time

PropertiesA type of synchronization

Used to enforce mutual exclusion

Thread can acquire / release locks

Thread will wait to acquire lock (stop execution)

If lock held by another thread

Page 11: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Synchronized Objects in Java

All Java objects provide locksApply synchronized keyword to object

Mutual exclusion for code in synchronization block

Example Object x = new Object();

void foo() {

synchronized(x) { // acquire lock on x on entry

... // hold lock on x in block

} // release lock on x on exitblo

ck

Page 12: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Synchronized Methods In Java

Java methods also provide locks Apply synchronized keyword to method

Mutual exclusion for entire body of method

Synchronizes on object invoking method

Example synchronized void foo() { …code… }

// shorthand notation for

void foo() {

synchronized (this) { …code… }

}

block

Page 13: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Synchronized Methods In Java

Page 14: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Locks in Java

PropertiesNo other thread can get lock on x while in blockDoes not protect fields of x

except by convention

other threads can access/update fields

but can’t obtain lock on xBy convention, lock x to obtain exclusive access to xLocked block of code critical section

Lock is released when block terminatesNo matter how the block terminates:

End of block reached

Exit block due to return, continue, break

Exception thrown

Page 15: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Using synchronization

public class UseSynchronization implements Runnable { static int x = 0;

static Object lock = new Object(); public void run() {

synchronized(lock) { int tmp = x;

x = tmp+1; }

}}

Page 16: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Questions

What would happen if the lock field were not static?

Why don’t we just make the run method synchronized?

Why don’t we just synchronize on x?

Page 17: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Not sharing same lock

public class NotSharingLock implements Runnable { static int x = 0;

Object lock = new Object(); public void run() {

synchronized(lock) { int tmp = x;

x = tmp+1; }

}}

Page 18: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Synchronization Issues

Use same lock to provide mutual exclusion

Ensure atomic transactions

Avoiding deadlock

Page 19: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Issue 1) Using Same Lock

Potential problemMutual exclusion depends on threads acquiring same lock

No synchronization if threads have different locks

Example void run() { Object o = new Object(); // different o per thread synchronized(o) { … // potential data race } }

Page 20: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Locks in Java

Single lock for all threads (mutual exclusion)

Separate locks for each thread (no synchronization)

Page 21: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Potential problemSequence of actions must be performed as single atomic transaction to avoid data race

Ensure lock is held for duration of transaction

Example synchronized(lock) { int tmp = x; // both statements must

// be executed together x = tmp; // by single thread }

Issue 2) Atomic Transactions

Page 22: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Using synchronization

public class InsuffientAtomicity implements Runnable {

static int x = 0;static Object lock = new Object();

public void run() { int tmp; synchronized(lock) {

tmp = x; }; synchronized(lock) {

x = tmp+1; }

}

Page 23: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Issue 3) Avoiding Deadlock

In general, want to be careful about performing any operations that might take a long time while holding a lock

What could take a really long time?getting another lock

Particularly if you get deadlock

Page 24: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Deadlock Example 1

Thread1() { Thread2() { synchronized(a) { synchronized(b) { synchronized(b) { synchronized(a) { … … } } } }} }

// Thread1 holds lock for a, waits for b// Thread2 holds lock for b, waits for a

Page 25: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Deadlock Example 2

void moveMoney(Account a, Account b, int amount) { synchronized(a) { synchronized(b) {

a.debit(amount); b.credit(amount); } }}

Thread1() { moveMoney(a,b,10); } // holds lock for a, waits for b

Thread2() { moveMoney(b,a,100); } // holds lock for b, waits for a

Page 26: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Waiting for Godot

Sometimes, you need to wait for another thread else to do something before you can do something

Page 27: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Abstract Data Type – Buffer

Buffer Transfers items from producers to consumers

Very useful in multithreaded programs

Synchronization needed to prevent multiple consumers removing same item

Page 28: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Buffer usage

Producer threadcalls buffer.add(o)

adds o to the buffer

Consumer threadcalls buffer.remove()

if object in buffer, removes and returns it

otherwise, waits until object is available to remove

Page 29: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Buffer Implementation

public class Buffer { private LinkedList objects = new LinkedList(); public synchronized add( Object x ) { objects.add(x); } public synchronized Object remove() { while (objects.isEmpty()) { ; // waits for more objects to be added } return objects.removeFirst(); }} // if empty buffer, remove() holds lock and waits // prevents add() from working deadlock

Page 30: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Eliminating Deadlock

public class Buffer { private Object [] myObjects; private int numberObjects = 0; public synchronized add( Object x ) { objects.add(x); } } public Object remove() { while (true) { // waits for more objects to be

added synchronize(this) { if (!objects.isEmpty()) {

return objects.removeFirst(); } } } } // if empty buffer, remove() gives

// up lock for a moment

Page 31: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Works barely, if at all

Might work

But waiting thread is going to be running a full tilt, twiddling its thumbs, doing nothing

burning up your battery life

keeping the producer from getting the CPU time it needs to quickly produce a new object

Page 32: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Issue 4) Using Wait & Notify

Potential problemThreads actively waiting consume resources

SolutionCan wait to be notified

Use Thread class methods wait(), notifyAll()

notify() is for advanced use and tricky to get right; avoid it

Page 33: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Thread Class Wait & Notify Methods

wait() Invoked on object

must already hold lock on that object

gives up lock on that object

goes into a wait state

notifyAll() Invoked on object

must already hold lock on that object

all threads waiting on that object are woken up

but they all gave up their lock when they performed wait

will have to regain lock before then can run

thread performing notify holds lock at the moment

Page 34: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Using Wait & Notify

State transitions

Page 35: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Using Wait and NotifyAll

public class Buffer { private LinkedList objects = new LinkedList(); public synchronized add( Object x ) { objects.add(x);

this.notifyAll(); } public synchronized Object remove() { while (objects.isEmpty()) {

this.wait(); } return objects.removeFirst(); }}

Page 36: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Actually, that won’t compile

the wait() method is declared to throw an InterruptedException

a checked exception

You rarely have situations where a wait will throw an InterruptedException

but the compiler forces you to deal with it

Page 37: Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.

Using Wait and NotifyAll

public class Buffer { private LinkedList objects = new LinkedList(); public synchronized add( Object x ) { objects.add(x);

this.notifyAll(); } public synchronized Object remove() { while (objects.isEmpty()) {

try { this.wait(); } catch (InterruptedException e) {}

} return objects.removeFirst(); }}