synchronization in java - uw computer sciences user...

26
506 CS 538 Spring 2006 © Synchronization in Java We often want threads to co-operate, typically in how they access shared data structures. Since thread execution is asynchronous, the details of how threads interact can be unpredictable. Consider a method update() { n = n+1; val = f(n); } that updates fields of an object. If two or more threads execute update concurrently, we might get unexpected or even illegal behavior. (Why?)

Upload: voduong

Post on 11-Dec-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

506CS 538 Spring 2006©

Synchronization in JavaWe often want threads to co-operate,typically in how they access shareddata structures.Since thread execution isasynchronous, the details of howthreads interact can be unpredictable.Consider a method update() {

n = n+1;

val = f(n);

}

that updates fields of an object.If two or more threads executeupdate concurrently, we might getunexpected or even illegal behavior.(Why?)

507CS 538 Spring 2006©

A Java method may be synchronized,which guarantees that at most onethread can execute the method at atime. Other threads wishing access,are forced to wait until the currentlyexecuting thread completes.Thusvoid synchronized update() { ... }

can safely be used to update anobject, even if multiple threads areactive.There is also a synchronizedstatement in Java that forces threadsto execute a block of codesequentially.synchronized(obj) {

obj.n = obj.n+1;

obj.val = f(obj.n);

}

508CS 538 Spring 2006©

Synchronization PrimitivesThe following operations are providedto allow threads to safely interact:wait() Sleep until awakenedwait(n) Sleep until awakened

or until n millisecondspass

notify() Wake up one sleepingthread

notifyAll() Wake up all sleepingthreads

Using these primitives, correctconcurrent access to a shared datastructure can be programed.

509CS 538 Spring 2006©

Consider a Buffer class in whichindependent threads may try to storeor fetch data objects:

class Buffer { private Queue q; Buffer() { q = new Queue(); } public synchronized void put(Object obj) { q.enqueue(obj); notify(); //Why is this needed? } public synchronized Object get() { while (q.isEmpty()) {

//Why a while loop? wait(); } return q.dequeue(); }}

510CS 538 Spring 2006©

Locks, Semaphores andMonitors

Java’s synchronization mechanismsare based upon the notion of a lock. Alock is a special value that can beheld by at most one thread.If a thread holds a lock, it haspermission to do some “critical”operation like writing a sharedvariable or restructuring a shareddata object.If a thread wants to do an operationbut doesn’t hold the necessary lock, itmust wait until it gets the lock.In Java there is a lock associated witheach run-time object.

511CS 538 Spring 2006©

Lock Granularity and AccessThough each Java object has a lock,you often don’t want to lock andunlock each object you access.If you are manipulating a large datastructure (like a tree or hash table),acquiring the lock for each object inthe tree or table can be costly anderror-prone.Instead, it is common to create a lockcorresponding to a group of objects.Hence holding the lock to the root ofa tree may give you permission toaccess the whole tree.There is a danger though—if all ormost of a large structure is held byone thread, then other threads won’tbe able to access that structureconcurrently.

512CS 538 Spring 2006©

For example, a large shared data base(like one used to record currentbookings for an airline) shouldn’t beheld exclusively by one thread—hundreds of concurrent threads maywant to access it at any time. Anintermediate lock, like all reservationsfor a single fight, is more reasonable.There is also an issue of how long youhold a lock. The ideal is to haveexclusive access for as short a periodas is necessary. Work that is notsubject to interference by otherthreads (like computations using localvariables) should be done before alock is obtained. Hence Java’ssynchronized statement allows amethod to get exclusive access to anobject for a limited region, enhancingshared access.

513CS 538 Spring 2006©

DeadlockA variety of programming problemsappear in concurrent programs thatdon’t exist in ordinary sequentialprograms.The most serious of these is deadlock:Two or more threads hold locks thatother threads require. Each waits forthe other thread to release a neededlock, and no thread is able to execute.As an example of how deadlock mayoccur, consider two threads, t1 andt2 . Each requires two files, a masterfile and a log file. Since these files areshared, each has a lock.Assume t1 gets the lock for themaster file while t2 (at the sameinstant) gets the lock for the log file.

514CS 538 Spring 2006©

Now each is stuck. Each has one file,and will wait forever for the other fileto be released.In Java deadlock avoidance is whollyup to the programmer. There are nolanguage-level guarantees thatdeadlock can’t happen.Some languages have experimentedwith ways to help programmers avoiddeadlock:• If all locks must be claimed at once,

deadlock can be avoided. You eitherget all of them or none, but you can’tblock other threads while making noprogress yourself.

• Locks (and the resources theycontrol) can be ordered, with the rulethat you must acquire locks in the

515CS 538 Spring 2006©

proper order. Now two threads can’teach hold locks the other needs.

• The language can require that thelargest set of locks ever needed bedeclared in advance. When locks arerequested, the operating system cantrack what’s claimed and what maybe needed, and refuse to honorunsafe requests.

516CS 538 Spring 2006©

Fairness & StarvationWhen one thread has a lock, otherthreads who want the lock will besuspended until the lock is released.It can happen that a waiting threadmay be forced to wait indefinitely toacquire a lock, due to an unfairwaiting policy. A waiting thread thatnever gets a lock it needs due tounfair lock allocation faces starvation.As an example, if we place waitingthreads on a stack, newly arrivedthreads will get access to a lockbefore earlier arrivals. This can lead tostarvation. Most thread managers tryto be fair and guarantee that allwaiting threads have a fair chance toacquire a lock.

517CS 538 Spring 2006©

How are Locks Implemented?Internally, Java needs operations toacquire a lock and release a lock.These operations can be implementedusing the notion of a semaphore.A semaphore is an integer value(often just a single bit) with twoatomic operations: up and down.up(s) increments s atomically.down(s) decrements s atomically.But if s is already zero, the processdoing the down operation is put in await state until s becomes positive(eventually some other process shoulddo an up operation).Now locks are easy to implement.You do a down(lock) to claim a lock.If someone else has it, you are forced

518CS 538 Spring 2006©

to wait until the lock is released. Ifthe lock value is > 0 you get it and allothers are “locked out.”When you want to release a lock, youdo up(lock) , which makes locknon-zero and eligible for anotherthread to claim.In fact, since only one thread will everhave a lock, the lock value needs tobe only one bit, with 1 meaningcurrently free and unlocked and 0meaning currently claimed andlocked.

519CS 538 Spring 2006©

MonitorsDirect manipulation of semaphores istedious and error-prone. If youacquire a lock but forget to release it,threads may be blocked forever.Depending on where down and upoperations are placed, it may bedifficult to understand howsynchronization is being performed.Few modern languages allow directuse of semaphores. Instead,semaphores are used in theimplementation of higher-levelconstructs like monitors.A monitor is a language constructthat guarantees that a block of codewill be executed synchronously (onethread at a time).

520CS 538 Spring 2006©

The Java synchronized statement isa form of monitor.Whensynchronized(obj) { ... }

is executed, “invisible” getLock andfreeLock operations are added:synchronized(obj) { getLock(obj)

...

freeLock(obj);

}

This allows the body of thesynchronized statement to executeonly when it has the lock for obj .Thus two different threads can neversimultaneously execute the body of asynchronized statement becausetwo threads can’t simultaneously holdobj ’s lock.

521CS 538 Spring 2006©

In fact, synchronized methods arereally just methods whose bodies areenclosed in an invisiblesynchronized statement.If we execute obj.method()

where method is synchronized,method ’s body is executed as if itwere of the formsynchronized(obj) {

body of method

}

Operations like sleep , wait , notifyand notifyAll also implicitly causethreads to release locks, allowingother threads to proceed.

522CS 538 Spring 2006©

Reading Assignment• A Comparative Overview of C#

(linked from class web page)

523CS 538 Spring 2006©

Java 1.5 (Tiger Java)Recently, Java has been extended toinclude a variety of improvements,many drawn from functionallanguages.Added features include:• Parametric polymorphism.

Classes and interfaces may beparameterized using a type parameter.class List<T> {

T head;

List<T> tail;

}

Interfaces may also be parameterized.

• Enhanced loop iterators.for (v : myArray) {

// each element of myArray // appears as a value of v }

524CS 538 Spring 2006©

• Automatic boxing and unboxing ofwrapper classes.

Conversion from int to Integer orInteger to int is now automatic.

• Typesafe enumerations.public enum Color {RED, BLUE, GREEN};

• Static imports.You may import all static members of aclass and use them withoutqualification. Thus you may now writeout.println rather thanSystem.out.println .

• Variable argument methods.

• Formatted output using printf :out.printf("Ans = %3d",a+b);

525CS 538 Spring 2006©

C#C# is Microsoft’s answer to Java. Inmost ways it is very similar to Java,with some C++ concepts reintroducedand some useful new features.Similarities to Java include:• C# is object-based, with all objected

descended from class Object .

• Objects are created from classes usingnew. All objects are heap-allocatedand garbage collection is provided.

• All code is placed within methodswhich must be defined within classes.

• Almost all Java reserved words haveC# equivalents (many are identical).

• Classes have single inheritance.

526CS 538 Spring 2006©

• C# generates code for a virtualmachine to support cross-platformexecution.

• Interfaces are provided to capturefunctionality common to manyclasses.

• Exceptions are very similar in form toJava’s.

• Instance and static data within anobject must be initialized at point ofcreation.

527CS 538 Spring 2006©

C# Improves Upon Some JavaFeatures

• Operators as well as methods can beoverloaded:

class Point { int x, y; static Point operator + ( Point p1, Point p2) { return new Point(p1.x+p2.x,

p1.y+p2.y); } }

• Switch statements may be indexed bystring literals.

• In a switch, fall throughs to the nextcase are disallowed (if non-empty).

• Goto’s are allowed.

• Virtual methods must be marked.

528CS 538 Spring 2006©

• Persistent objects (that may be storedacross executions) are available.

529CS 538 Spring 2006©

C# Adds Useful Features• Events and delegates are included to

handle asynchronous actions (likekeyboard or mouse actions).

• Properties allow user-defined readand write actions for fields. You canadd get and set methods to thedefinition of a field. For example,

class Customer {

private string name;

public string Name {

get { return name; }}

}

Customer c; ...

string s = c.Name;

530CS 538 Spring 2006©

• Indexers allow objects other thanarrays to be indexed. The [] operatoris overloadable. This allows you todefine the meaning ofobj[123] or obj["abc"]within any class definition.

• Collection classes may be directlyenumerated:foreach (int i in array) ...

• Fields, methods and constructors maybe defined within a struct as well as aclass. Structs are allocated within thestack instead of the heap, and arepassed by value. For example:

struct Point {

int x,y;

void reset () {

x=0; y=0; }

}

531CS 538 Spring 2006©

• When an object is needed, a primitive(int , char , etc.) or a struct will beautomatically boxed or unboxedwithout explicit use of a wrapperclass (like Integer or Character ).Thus if method List.add expects anobject, you may write

List.add(123);and 123 will be boxed into anInteger object automatically.

• Enumerations are provided:enum Color {Red, Blue, Green};

• Rectangular arrays are provided:int [,] multi = new int[5,5];

• Reference, out and variable-lengthparameter lists are allowed.

• Pointers may be used in methodsmarked unsafe .