SlideShare a Scribd company logo
Concurrent
Programming
06
Sachintha Gunasena MBCS
http://lk.linkedin.com/in/sachinthadtg
Recap so far…
Sachintha Gunasena MBCS
http://lk.linkedin.com/in/sachinthadtg
Previous Session
• Processes & Threads
• Thread Objects
• Defining & Starting a Thread
• Pausing Execution with Sleep
• Interrupts
• Joins
• The Simple Threads Example
• Synchronisation
• Thread Interference
• Memory Consistency Errors
Today…
Today’s Session
• Synchronization
• Synchronised Methods
• Intrinsic Locks & Synchronisation
• Atomic Access
• Liveness
• Deadlock
• Starvation & Livestock
• Guarded Blocks
• Immutable Objects
• A Synchronized Class Example
• A Strategy for Defining Immutable Objects
Synchronization
Synchronized Methods
• To make a method synchronized, simply add the synchronized keyword to its
declaration: public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
Synchronized Methods
Cont.d
• If count is an instance of SynchronizedCounter, then making these methods synchronized has two
effects:
• First, it is not possible for two invocations of synchronized methods on the same object to
interleave.
• 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
• Second, when a synchronized method exits, it automatically establishes a happens-before
relationship with any subsequent invocation of a synchronized method for the same object.
• This guarantees that changes to the state of the object are visible to all threads
• constructors cannot be synchronized
• using the synchronized keyword with a constructor is a syntax error.
• because only the thread that creates an object should have access to it while it is being
constructed.
Synchronized Methods
Cont.d
• Warning:
• When constructing an object that will be shared between threads, be
very careful that a reference to the object does not "leak"
prematurely.
• For example, suppose you want to maintain a List called instances
containing every instance of class.
• You might be tempted to add the following line to your constructor:
• But then other threads can use instances to access the object before
construction of the object is complete.
instances.add(this);
Synchronized Methods
Cont.d
• Synchronized methods enable a simple strategy for preventing
thread interference and memory consistency errors:
• if an object is visible to more than one thread, all reads or writes
to that object's variables are done through synchronized
methods.
• (An important exception: final fields, which cannot be modified
after the object is constructed, can be safely read through non-
synchronized methods, once the object is constructed)
• This strategy is effective, but can present problems with
liveness, as we'll see later.
Intrinsic Locks and
Synchronization
• Synchronization is built around an internal entity known as
the intrinsic lock or monitor lock.
• (The API specification often refers to this entity simply as a
"monitor.")
• Intrinsic locks play a role in both aspects of synchronization:
• enforcing exclusive access to an object's state and
• establishing happens-before relationships that are
essential to visibility.
Intrinsic Locks and
Synchronization Cont.d
• Every object has an intrinsic lock associated with it.
• By convention, a thread that needs exclusive and consistent access to an
object's fields has to acquire the object's intrinsic lock before accessing them,
and then release the intrinsic lock when it's done with them.
• A thread is said to own the intrinsic lock between the time it has acquired the
lock and released the lock.
• As long as a thread owns an intrinsic lock, no other thread can acquire the
same lock.
• The other thread will block when it attempts to acquire the lock.
• When a thread releases an intrinsic lock, a happens-before relationship is
established between that action and any subsequent acquisition of the same
lock.
Locks In Synchronized
Methods
• When a thread invokes a synchronized method, it automatically acquires
the intrinsic lock for that method's object and releases it when the
method returns.
• The lock release occurs even if the return was caused by an uncaught
exception.
• You might wonder what happens when a static synchronized method is
invoked, since a static method is associated with a class, not an object.
• In this case, the thread acquires the intrinsic lock for the Class object
associated with the class.
• Thus access to class's static fields is controlled by a lock that's distinct
from the lock for any instance of the class.
Synchronized Statements
• Another way to create synchronized code is with synchronized statements.
• Unlike synchronized methods, synchronized statements must specify the
object that provides the intrinsic lock:
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
Synchronized Statements
Cont.d
• In this example, the addName method needs to synchronize changes to lastName and nameCount, but
also needs to avoid synchronizing invocations of other objects' methods.
• (Invoking other objects' methods from synchronized code can create problems that are described in the
section on Liveness.)
• Without synchronized statements, there would have to be a separate, unsynchronized method for the sole
purpose of invoking nameList.add.
• Synchronized statements are also useful for improving concurrency with fine-grained synchronization.
• Suppose, for example, class MsLunch has two instance fields, c1 and c2, that are never used together.
• All updates of these fields must be synchronized, but there's no reason to prevent an update of c1 from
being interleaved with an update of c2 — and doing so reduces concurrency by creating unnecessary
blocking.
• Instead of using synchronized methods or otherwise using the lock associated with this, we create two
objects solely to provide locks.
• You must be absolutely sure that it really is safe to interleave access of the affected fields.
Synchronized Statements
Cont.d
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++;
}
}
}
Re-entrant Synchronization
• Recall that a thread cannot acquire a lock owned by another thread.
• But a thread can acquire a lock that it already owns.
• Allowing a thread to acquire the same lock more than once enables
reentrant synchronization.
• This describes a situation where synchronized code, directly or
indirectly, invokes a method that also contains synchronized code,
and both sets of code use the same lock.
• Without reentrant synchronization, synchronized code would have to
take many additional precautions to avoid having a thread cause
itself to block.
Atomic Access
• one that effectively happens all at once.
• An atomic action cannot stop in the middle:
• it either happens completely,
• or it doesn't happen at all.
• No side effects of an atomic action are visible until the action is complete.
• We have already seen that an increment expression, such as c++, does not describe an atomic action.
• Even very simple expressions can define complex actions that can decompose into other actions.
• However, there are actions you can specify that are atomic:
• Reads and writes are atomic for reference variables and 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)
Atomic Access Cont.d
• Atomic actions cannot be interleaved, so they can be used without fear of thread interference.
• However, this does not eliminate all need to synchronize atomic actions, because memory
consistency errors are still possible.
• Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile
variable establishes a happens-before relationship with subsequent reads of that same variable.
• This means that changes to a volatile variable are always visible to other threads.
• What's more, it also means that when a thread reads a volatile variable, it sees not just the latest
change to the volatile, but also the side effects of the code that led up the change.
• Using simple atomic variable access is more efficient than accessing these variables through
synchronized code, but requires more care by the programmer to avoid memory consistency errors.
• Whether the extra effort is worthwhile depends on the size and complexity of the application.
• Some of the classes in the java.util.concurrent package provide atomic methods that do not rely on
synchronization.
Liveness
Liveness
• A concurrent application's ability to execute in a
timely manner is known as its liveness.
• This section covers the most common kind of
liveness problem, deadlock, and goes on to
briefly describe two other liveness problems,
starvation and livelock.
Deadlock
• a situation where two or more threads are blocked forever, waiting for each
other
• e.g.:
• Tom and Jerry are friends, and great believers in courtesy.
• A strict rule of courtesy is that when you bow to a friend, you must remain
bowed until your friend has a chance to return the bow.
• Unfortunately, this rule does not account for the possibility that two friends
might bow to each other at the same time.
• This example application, Deadlock, models this possibility:
• When Deadlock runs, it's extremely likely that both threads will block when
they attempt to invoke bowBack.
Deadlock Cont.dpublic class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s"
+ " has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s"
+ " has bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend tom =
new Friend("Tom");
final Friend jerry =
new Friend("Jerry");
new Thread(new Runnable() {
public void run() { tom.bow(jerry); }
}).start();
new Thread(new Runnable() {
public void run() { jerry.bow(tom); }
}).start();
}
}
Deadlock Cont.d
• When Deadlock runs, it's extremely likely that
both threads will block when they attempt to
invoke bowBack.
• Neither block will ever end, because each thread
is waiting for the other to exit bow.
Starvation & Livelock
• Starvation and livelock are much less common a
problem than deadlock,
• but are still problems that every designer of
concurrent software is likely to encounter.
Starvation
• a situation where a thread is unable to gain regular access to shared
resources and is unable to make progress.
• This happens when shared resources are made unavailable for long
periods by "greedy" threads.
• For example,
• suppose an object provides a synchronized method that often
takes a long time to return.
• If one thread invokes this method frequently,
• other threads that also need frequent synchronized access to
the same object will often be blocked.
Livelock
• A thread often acts in response to the action of another thread.
• If the other thread's action is also a response to the action of another thread, then
livelock may result.
• As with deadlock, livelocked threads are unable to make further progress.
• However, the threads are not blocked — they are simply too busy responding to each
other to resume work.
• This is comparable to two people attempting to pass each other in a corridor:
• Tom moves to his left to let Jerry pass, while Jerry moves to his right to let Tom
pass.
• Seeing that they are still blocking each other, Tom moves to his right, while Jerry
moves to his left.
• They're still blocking each other, so...
Guarded Blocks
Guarded Blocks
• Threads often have to coordinate their actions.
• The most common coordination idiom is the guarded block.
• Such a block begins by polling a condition that must be true before the block
can proceed.
• There are a number of steps to follow in order to do this correctly.
• Suppose, for example guardedJoy is a method that must not proceed until a
shared variable joy has been set by another thread.
• Such a method could,
• in theory, simply loop until the condition is satisfied,
• but that loop is wasteful, since it executes continuously while waiting.
Guarded Blocks Cont.d
public void guardedJoy() {
// Simple loop guard. Wastes
// processor time. Don't do this!
while(!joy) {}
System.out.println("Joy has been achieved!");
}
Guarded Blocks Cont.d
• A more efficient guard invokes Object.wait to
suspend the current thread.
• The invocation of wait does not return until
another thread has issued a notification that
some special event may have occurred
• — though not necessarily the event this thread is
waiting for:
Guarded Blocks Cont.d
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
Guarded Blocks Cont.d
• Note:
• Always invoke wait inside a loop that tests for the
condition being waited for.
• Don't assume that
• the interrupt was for the particular condition
you were waiting for,
• or that the condition is still true.
Guarded Blocks Cont.d
• Like many methods that suspend execution, wait can throw InterruptedException.
• In this example, we can just ignore that exception — we only care about the value of joy.
• Why is this version of guardedJoy synchronized?
• Suppose d is the object we're using to invoke wait.
• When a thread invokes d.wait, it must own the intrinsic lock for d — otherwise an error is thrown.
• Invoking wait inside a synchronized method is a simple way to acquire the intrinsic lock.
• When wait is invoked, the thread releases the lock and suspends execution.
• At some future time,
• another thread will acquire the same lock and invoke Object.notifyAll,
• informing all threads waiting on that lock that something important has happened:
Guarded Blocks Cont.d
• Some time after the second thread has released
the lock,
• the first thread reacquires the lock and resumes
• by returning from the invocation of wait.
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
Guarded Blocks Cont.d
• Note:
• There is a second notification method, notify, which wakes up a
single thread.
• Because notify doesn't allow you to specify the thread that is woken
up,
• it is useful only in massively parallel applications
• — that is, programs with a large number of threads, all doing
similar chores.
• In such an application, you don't care which thread gets woken up.
Guarded Blocks Cont.d
• Let's use guarded blocks to create a Producer-Consumer application.
• This kind of application shares data between two threads:
• the producer, that creates the data,
• and the consumer, that does something with it.
• The two threads communicate using a shared object.
• Coordination is essential:
• the consumer thread must not attempt to retrieve the data before the producer thread has
delivered it,
• and the producer thread must not attempt to deliver new data if the consumer hasn't retrieved
the old data.
• In this example,
• the data is a series of text messages, which are shared through an object of type Drop:
Guarded Blocks Cont.dpublic class Drop {
// Message sent from producer
// to consumer.
private String message;
// True if consumer should wait
// for producer to send message,
// false if producer should wait for
// consumer to retrieve message.
private boolean empty = true;
public synchronized String take() {
// Wait until message is
// available.
while (empty) {
try {
wait();
} catch (InterruptedException e) {}
}
// Toggle status.
empty = true;
// Notify producer that
// status has changed.
notifyAll();
return message;
}
public synchronized void put(String message) {
// Wait until message has
// been retrieved.
while (!empty) {
try {
wait();
} catch (InterruptedException e) {}
}
// Toggle status.
empty = false;
// Store message.
this.message = message;
// Notify consumer that status
// has changed.
notifyAll();
}
}
Guarded Blocks Cont.d
• The producer thread, defined in Producer, sends a
series of familiar messages.
• The string "DONE" indicates that all messages
have been sent.
• To simulate the unpredictable nature of real-world
applications,
• the producer thread pauses for random intervals
between messages.
Guarded Blocks Cont.d
import java.util.Random;
public class Producer implements Runnable {
private Drop drop;
public Producer(Drop drop) {
this.drop = drop;
}
public void run() {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
Random random = new Random();
for (int i = 0;
i < importantInfo.length;
i++) {
drop.put(importantInfo[i]);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
}
drop.put("DONE");
}
}
Guarded Blocks Cont.d
• The consumer thread,
• defined in Consumer,
• simply retrieves the messages and prints them
out,
• until it retrieves the "DONE" string.
• This thread also pauses for random intervals.
Guarded Blocks Cont.d
import java.util.Random;
public class Consumer implements Runnable {
private Drop drop;
public Consumer(Drop drop) {
this.drop = drop;
}
public void run() {
Random random = new Random();
for (String message = drop.take();
! message.equals("DONE");
message = drop.take()) {
System.out.format("MESSAGE RECEIVED: %s%n", message);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
}
}
}
Guarded Blocks Cont.d
• Finally, here is the main thread, defined in ProducerConsumerExample, that
launches the producer and consumer threads.
• Note: The Drop class was written in order to demonstrate guarded blocks. To
avoid re-inventing the wheel, examine the existing data structures in the Java
Collections Framework before trying to code your own data-sharing objects.
public class ProducerConsumerExample {
public static void main(String[] args) {
Drop drop = new Drop();
(new Thread(new Producer(drop))).start();
(new Thread(new Consumer(drop))).start();
}
}
Immutable Objects
Immutable Objects
• An object is considered immutable if its state cannot change after it is constructed.
• Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable
code.
• Immutable objects are particularly useful in concurrent applications.
• Since they cannot change state, they cannot be corrupted by thread interference or observed in an
inconsistent state.
• Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a
new object as opposed to updating an object in place.
• The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated
with immutable objects.
• These include decreased overhead due to garbage collection, and the elimination of code needed to protect
mutable objects from corruption.
• The following subsections take a class whose instances are mutable and derives a class with immutable
instances from it.
• In so doing, they give general rules for this kind of conversion and demonstrate some of the advantages of
immutable objects.
A Synchronized Class
Example
• The class, SynchronizedRGB, defines objects
that represent colors.
• Each object represents the color as three integers
that stand for primary color values and a string
that gives the name of the color.
A Synchronized Class
Example Cont.dpublic class SynchronizedRGB {
// Values must be between 0 and 255.
private int red;
private int green;
private int blue;
private String name;
private void check(int red,
int green,
int blue) {
if (red < 0 || red > 255
|| green < 0 || green > 255
|| blue < 0 || blue > 255) {
throw new IllegalArgumentException();
}
}
public SynchronizedRGB(int red,
int green,
int blue,
String name) {
check(red, green, blue);
this.red = red;
this.green = green;
this.blue = blue;
this.name = name;
}
public void set(int red,
int green,
int blue,
String name) {
check(red, green, blue);
synchronized (this) {
this.red = red;
this.green = green;
this.blue = blue;
this.name = name;
}
}
public synchronized int getRGB() {
return ((red << 16) | (green << 8) | blue);
}
public synchronized String getName() {
return name;
}
public synchronized void invert() {
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
name = "Inverse of " + name;
}
}
A Synchronized Class
Example Cont.d
• SynchronizedRGB must be used carefully to avoid being seen in an
inconsistent state.
• Suppose, for example, a thread executes the following code:
• If another thread
• invokes color.set after Statement 1 but before Statement 2,
• the value of myColorInt won't match the value of myColorName.
SynchronizedRGB color =
new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
int myColorInt = color.getRGB(); //Statement 1
String myColorName = color.getName(); //Statement 2
A Synchronized Class
Example Cont.d
• To avoid this outcome, the two statements must be
bound together:
• This kind of inconsistency is only possible for mutable
objects
• — it will not be an issue for the immutable version of
SynchronizedRGB.
synchronized (color) {
int myColorInt = color.getRGB();
String myColorName = color.getName();
}
A Strategy for Defining
Immutable Objects
• The following rules define a simple strategy for creating
immutable objects.
• Not all classes documented as "immutable" follow these rules.
• This does not necessarily mean the creators of these classes
were sloppy
• — they may have good reason for believing that instances of
their classes never change after construction.
• However, such strategies require sophisticated analysis and
are not for beginners.
A Strategy for Defining
Immutable Objects Cont.d
• Don't provide "setter" methods
• — methods that modify fields or objects referred to by fields.
• Make all fields final and private.
• Don't allow subclasses to override methods.
• The simplest way to do this is to declare the class as final.
• A more sophisticated approach is to
• make the constructor private and construct instances in
factory methods.
A Strategy for Defining
Immutable Objects Cont.d
• If the instance fields include references to mutable objects,
• don't allow those objects to be changed:
• Don't provide methods that modify the mutable objects.
• Don't share references to the mutable objects.
• Never store references to external, mutable objects passed to the
constructor;
• if necessary, create copies, and store references to the copies.
• Similarly, create copies of your internal mutable objects when necessary
• to avoid returning the originals in your methods.
A Strategy for Defining
Immutable Objects Cont.d
• Applying this strategy to SynchronizedRGB results in the following steps:
• There are two setter methods in this class.
• The first one, set, arbitrarily transforms the object, and has no place in an immutable
version of the class.
• The second one, invert, can be adapted by having it create a new object instead of
modifying the existing one.
• All fields are already private; they are further qualified as final.
• The class itself is declared final.
• Only one field refers to an object, and that object is itself immutable. Therefore, no
safeguards against changing the state of "contained" mutable objects are necessary.
• After these changes, we have ImmutableRGB:
A Strategy for Defining
Immutable Objects Cont.d
final public class ImmutableRGB {
// Values must be between 0 and 255.
final private int red;
final private int green;
final private int blue;
final private String name;
private void check(int red,
int green,
int blue) {
if (red < 0 || red > 255
|| green < 0 || green > 255
|| blue < 0 || blue > 255) {
throw new IllegalArgumentException();
}
}
public ImmutableRGB(int red,
int green,
int blue,
String name) {
check(red, green, blue);
this.red = red;
this.green = green;
this.blue = blue;
this.name = name;
}
public int getRGB() {
return ((red << 16) | (green << 8) | blue);
}
public String getName() {
return name;
}
public ImmutableRGB invert() {
return new ImmutableRGB(255 - red,
255 - green,
255 - blue,
"Inverse of " + name);
}
}
Next Up…
Next Session
• High Level Concurrency Objects
Sachintha Gunasena MBCS
http://lk.linkedin.com/in/sachinthadtg
Thank you.
Sachintha Gunasena MBCS
http://lk.linkedin.com/in/sachinthadtg
Ad

Recommended

Concurrency Programming in Java - 05 - Processes and Threads, Thread Objects,...
Concurrency Programming in Java - 05 - Processes and Threads, Thread Objects,...
Sachintha Gunasena
 
Java Performance, Threading and Concurrent Data Structures
Java Performance, Threading and Concurrent Data Structures
Hitendra Kumar
 
Threads And Synchronization in C#
Threads And Synchronization in C#
Rizwan Ali
 
Threading in C#
Threading in C#
Medhat Dawoud
 
C# Thread synchronization
C# Thread synchronization
Prem Kumar Badri
 
.NET: Thread Synchronization Constructs
.NET: Thread Synchronization Constructs
Sasha Kravchuk
 
[Java concurrency]02.basic thread synchronization
[Java concurrency]02.basic thread synchronization
xuehan zhu
 
.Net Threading
.Net Threading
Erik Ralston
 
Concurrency with java
Concurrency with java
Hoang Nguyen
 
multi threading
multi threading
Yaswanth Babu Gummadivelli
 
Sync, async and multithreading
Sync, async and multithreading
Tuan Chau
 
Threads c sharp
Threads c sharp
Karthick Suresh
 
Advanced Introduction to Java Multi-Threading - Full (chok)
Advanced Introduction to Java Multi-Threading - Full (chok)
choksheak
 
Java Multithreading
Java Multithreading
Rajkattamuri
 
Concurrency in c#
Concurrency in c#
RezaHamidpour
 
Thread model of java
Thread model of java
myrajendra
 
Multithreading Concepts
Multithreading Concepts
Arvind Krishnaa
 
Threads c sharp
Threads c sharp
Deivaa
 
Intro To .Net Threads
Intro To .Net Threads
rchakra
 
Threading
Threading
abhay singh
 
Thread
Thread
Juhi Kumari
 
Thread syncronization
Thread syncronization
priyabogra1
 
Java Multithreading and Concurrency
Java Multithreading and Concurrency
Rajesh Ananda Kumar
 
Synchronization.37
Synchronization.37
myrajendra
 
Concurrency
Concurrency
Ankur Maheshwari
 
Concurrency
Concurrency
Sandeep Chawla
 
Thread & concurrancy
Thread & concurrancy
Onkar Deshpande
 
22 multi threading iv
22 multi threading iv
Ravindra Rathore
 
Java Tutorials - Concurrency
Java Tutorials - Concurrency
Christian Rubiales
 
Java concurrency
Java concurrency
ducquoc_vn
 

More Related Content

What's hot (16)

Concurrency with java
Concurrency with java
Hoang Nguyen
 
multi threading
multi threading
Yaswanth Babu Gummadivelli
 
Sync, async and multithreading
Sync, async and multithreading
Tuan Chau
 
Threads c sharp
Threads c sharp
Karthick Suresh
 
Advanced Introduction to Java Multi-Threading - Full (chok)
Advanced Introduction to Java Multi-Threading - Full (chok)
choksheak
 
Java Multithreading
Java Multithreading
Rajkattamuri
 
Concurrency in c#
Concurrency in c#
RezaHamidpour
 
Thread model of java
Thread model of java
myrajendra
 
Multithreading Concepts
Multithreading Concepts
Arvind Krishnaa
 
Threads c sharp
Threads c sharp
Deivaa
 
Intro To .Net Threads
Intro To .Net Threads
rchakra
 
Threading
Threading
abhay singh
 
Thread
Thread
Juhi Kumari
 
Thread syncronization
Thread syncronization
priyabogra1
 
Java Multithreading and Concurrency
Java Multithreading and Concurrency
Rajesh Ananda Kumar
 
Synchronization.37
Synchronization.37
myrajendra
 
Concurrency with java
Concurrency with java
Hoang Nguyen
 
Sync, async and multithreading
Sync, async and multithreading
Tuan Chau
 
Advanced Introduction to Java Multi-Threading - Full (chok)
Advanced Introduction to Java Multi-Threading - Full (chok)
choksheak
 
Java Multithreading
Java Multithreading
Rajkattamuri
 
Thread model of java
Thread model of java
myrajendra
 
Threads c sharp
Threads c sharp
Deivaa
 
Intro To .Net Threads
Intro To .Net Threads
rchakra
 
Thread syncronization
Thread syncronization
priyabogra1
 
Java Multithreading and Concurrency
Java Multithreading and Concurrency
Rajesh Ananda Kumar
 
Synchronization.37
Synchronization.37
myrajendra
 

Similar to Concurrency Programming in Java - 06 - Thread Synchronization, Liveness, Guarded Blocks, Immutable Objects (20)

Concurrency
Concurrency
Ankur Maheshwari
 
Concurrency
Concurrency
Sandeep Chawla
 
Thread & concurrancy
Thread & concurrancy
Onkar Deshpande
 
22 multi threading iv
22 multi threading iv
Ravindra Rathore
 
Java Tutorials - Concurrency
Java Tutorials - Concurrency
Christian Rubiales
 
Java concurrency
Java concurrency
ducquoc_vn
 
Java Concurrency Starter Kit
Java Concurrency Starter Kit
Mark Papis
 
Multithreading in java programming language.ppt
Multithreading in java programming language.ppt
AutoAuto9
 
Multithreading and concurrency in android
Multithreading and concurrency in android
Rakesh Jha
 
Java concurrency in practice
Java concurrency in practice
Deon Huang
 
Concurrency: Best Practices
Concurrency: Best Practices
IndicThreads
 
Concurrency with java
Concurrency with java
Luis Goldster
 
Concurrency with java
Concurrency with java
James Wong
 
Concurrency with java
Concurrency with java
Young Alista
 
Concurrency with java
Concurrency with java
Harry Potter
 
Concurrency with java
Concurrency with java
Tony Nguyen
 
Concurrency with java
Concurrency with java
Fraboni Ec
 
Concurrency in Java
Concurrency in Java
Lakshmi Narasimhan
 
Concurrent Programming in Java
Concurrent Programming in Java
Lakshmi Narasimhan
 
Concurrency Learning From Jdk Source
Concurrency Learning From Jdk Source
Kaniska Mandal
 
Java concurrency
Java concurrency
ducquoc_vn
 
Java Concurrency Starter Kit
Java Concurrency Starter Kit
Mark Papis
 
Multithreading in java programming language.ppt
Multithreading in java programming language.ppt
AutoAuto9
 
Multithreading and concurrency in android
Multithreading and concurrency in android
Rakesh Jha
 
Java concurrency in practice
Java concurrency in practice
Deon Huang
 
Concurrency: Best Practices
Concurrency: Best Practices
IndicThreads
 
Concurrency with java
Concurrency with java
Luis Goldster
 
Concurrency with java
Concurrency with java
James Wong
 
Concurrency with java
Concurrency with java
Young Alista
 
Concurrency with java
Concurrency with java
Harry Potter
 
Concurrency with java
Concurrency with java
Tony Nguyen
 
Concurrency with java
Concurrency with java
Fraboni Ec
 
Concurrent Programming in Java
Concurrent Programming in Java
Lakshmi Narasimhan
 
Concurrency Learning From Jdk Source
Concurrency Learning From Jdk Source
Kaniska Mandal
 
Ad

More from Sachintha Gunasena (18)

Entrepreneurship and Commerce in IT - 14 - Web Marketing Communications
Entrepreneurship and Commerce in IT - 14 - Web Marketing Communications
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 13 - The Internet Audience, consumer be...
Entrepreneurship and Commerce in IT - 13 - The Internet Audience, consumer be...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 12 - Web Payments
Entrepreneurship & Commerce in IT - 12 - Web Payments
Sachintha Gunasena
 
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Sachintha Gunasena
 
Concurrency Programming in Java - 03 - Essentials of Java Part 2
Concurrency Programming in Java - 03 - Essentials of Java Part 2
Sachintha Gunasena
 
Concurrency Programming in Java - 02 - Essentials of Java Part 1
Concurrency Programming in Java - 02 - Essentials of Java Part 1
Sachintha Gunasena
 
Concurrency Programming in Java - 01 - Introduction to Concurrency Programming
Concurrency Programming in Java - 01 - Introduction to Concurrency Programming
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 11 - Security & Encryption
Entrepreneurship & Commerce in IT - 11 - Security & Encryption
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 08 - E-Commerce business models and concepts
Entrepreneurship & Commerce in IT - 08 - E-Commerce business models and concepts
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 10 - The Internet today and How to build ...
Entrepreneurship & Commerce in IT - 10 - The Internet today and How to build ...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 09 - The internet and the world wide web
Entrepreneurship & Commerce in IT - 09 - The internet and the world wide web
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 07 - Introduction to E-Commerce I - e-c...
Entrepreneurship and Commerce in IT - 07 - Introduction to E-Commerce I - e-c...
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 06 - Funding, Expanding, and Exit Strat...
Entrepreneurship and Commerce in IT - 06 - Funding, Expanding, and Exit Strat...
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 05 - Marketing, Technology and Marketin...
Entrepreneurship and Commerce in IT - 05 - Marketing, Technology and Marketin...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 01 - Introduction in to Entrepreneurship,...
Entrepreneurship & Commerce in IT - 01 - Introduction in to Entrepreneurship,...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 02 - Basic Concepts of Entrepreneurship, ...
Entrepreneurship & Commerce in IT - 02 - Basic Concepts of Entrepreneurship, ...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 04 - Marketing Plan, Marketing 7 P's, STP...
Entrepreneurship & Commerce in IT - 04 - Marketing Plan, Marketing 7 P's, STP...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 03 - Writing a Business Plan, Creating a ...
Entrepreneurship & Commerce in IT - 03 - Writing a Business Plan, Creating a ...
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 14 - Web Marketing Communications
Entrepreneurship and Commerce in IT - 14 - Web Marketing Communications
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 13 - The Internet Audience, consumer be...
Entrepreneurship and Commerce in IT - 13 - The Internet Audience, consumer be...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 12 - Web Payments
Entrepreneurship & Commerce in IT - 12 - Web Payments
Sachintha Gunasena
 
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Sachintha Gunasena
 
Concurrency Programming in Java - 03 - Essentials of Java Part 2
Concurrency Programming in Java - 03 - Essentials of Java Part 2
Sachintha Gunasena
 
Concurrency Programming in Java - 02 - Essentials of Java Part 1
Concurrency Programming in Java - 02 - Essentials of Java Part 1
Sachintha Gunasena
 
Concurrency Programming in Java - 01 - Introduction to Concurrency Programming
Concurrency Programming in Java - 01 - Introduction to Concurrency Programming
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 11 - Security & Encryption
Entrepreneurship & Commerce in IT - 11 - Security & Encryption
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 08 - E-Commerce business models and concepts
Entrepreneurship & Commerce in IT - 08 - E-Commerce business models and concepts
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 10 - The Internet today and How to build ...
Entrepreneurship & Commerce in IT - 10 - The Internet today and How to build ...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 09 - The internet and the world wide web
Entrepreneurship & Commerce in IT - 09 - The internet and the world wide web
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 07 - Introduction to E-Commerce I - e-c...
Entrepreneurship and Commerce in IT - 07 - Introduction to E-Commerce I - e-c...
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 06 - Funding, Expanding, and Exit Strat...
Entrepreneurship and Commerce in IT - 06 - Funding, Expanding, and Exit Strat...
Sachintha Gunasena
 
Entrepreneurship and Commerce in IT - 05 - Marketing, Technology and Marketin...
Entrepreneurship and Commerce in IT - 05 - Marketing, Technology and Marketin...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 01 - Introduction in to Entrepreneurship,...
Entrepreneurship & Commerce in IT - 01 - Introduction in to Entrepreneurship,...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 02 - Basic Concepts of Entrepreneurship, ...
Entrepreneurship & Commerce in IT - 02 - Basic Concepts of Entrepreneurship, ...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 04 - Marketing Plan, Marketing 7 P's, STP...
Entrepreneurship & Commerce in IT - 04 - Marketing Plan, Marketing 7 P's, STP...
Sachintha Gunasena
 
Entrepreneurship & Commerce in IT - 03 - Writing a Business Plan, Creating a ...
Entrepreneurship & Commerce in IT - 03 - Writing a Business Plan, Creating a ...
Sachintha Gunasena
 
Ad

Recently uploaded (20)

Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
Heat Treatment Process Automation in India
Heat Treatment Process Automation in India
Reckers Mechatronics
 
Reimagining Software Development and DevOps with Agentic AI
Reimagining Software Development and DevOps with Agentic AI
Maxim Salnikov
 
Open Source Software Development Methods
Open Source Software Development Methods
VICTOR MAESTRE RAMIREZ
 
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Philip Schwarz
 
From Data Preparation to Inference: How Alluxio Speeds Up AI
From Data Preparation to Inference: How Alluxio Speeds Up AI
Alluxio, Inc.
 
Azure AI Foundry: The AI app and agent factory
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
Zoneranker’s Digital marketing solutions
Zoneranker’s Digital marketing solutions
reenashriee
 
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
2nd Sight Lab
 
The Anti-Masterclass Live - Peak of Data & AI 2025
The Anti-Masterclass Live - Peak of Data & AI 2025
Safe Software
 
Complete WordPress Programming Guidance Book
Complete WordPress Programming Guidance Book
Shabista Imam
 
Best Practice for LLM Serving in the Cloud
Best Practice for LLM Serving in the Cloud
Alluxio, Inc.
 
Best MLM Compensation Plans for Network Marketing Success in 2025
Best MLM Compensation Plans for Network Marketing Success in 2025
LETSCMS Pvt. Ltd.
 
Download Adobe Illustrator Crack free for Windows 2025?
Download Adobe Illustrator Crack free for Windows 2025?
grete1122g
 
Automated Migration of ESRI Geodatabases Using XML Control Files and FME
Automated Migration of ESRI Geodatabases Using XML Control Files and FME
Safe Software
 
Microsoft-365-Administrator-s-Guide1.pdf
Microsoft-365-Administrator-s-Guide1.pdf
mazharatknl
 
IObit Driver Booster Pro 12 Crack Latest Version Download
IObit Driver Booster Pro 12 Crack Latest Version Download
pcprocore
 
Which Hiring Management Tools Offer the Best ROI?
Which Hiring Management Tools Offer the Best ROI?
HireME
 
ERP Systems in the UAE: Driving Business Transformation with Smart Solutions
ERP Systems in the UAE: Driving Business Transformation with Smart Solutions
dheeodoo
 
How Automation in Claims Handling Streamlined Operations
How Automation in Claims Handling Streamlined Operations
Insurance Tech Services
 
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
Heat Treatment Process Automation in India
Heat Treatment Process Automation in India
Reckers Mechatronics
 
Reimagining Software Development and DevOps with Agentic AI
Reimagining Software Development and DevOps with Agentic AI
Maxim Salnikov
 
Open Source Software Development Methods
Open Source Software Development Methods
VICTOR MAESTRE RAMIREZ
 
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Folding Cheat Sheet # 9 - List Unfolding 𝑢𝑛𝑓𝑜𝑙𝑑 as the Computational Dual of ...
Philip Schwarz
 
From Data Preparation to Inference: How Alluxio Speeds Up AI
From Data Preparation to Inference: How Alluxio Speeds Up AI
Alluxio, Inc.
 
Azure AI Foundry: The AI app and agent factory
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
Zoneranker’s Digital marketing solutions
Zoneranker’s Digital marketing solutions
reenashriee
 
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
2nd Sight Lab
 
The Anti-Masterclass Live - Peak of Data & AI 2025
The Anti-Masterclass Live - Peak of Data & AI 2025
Safe Software
 
Complete WordPress Programming Guidance Book
Complete WordPress Programming Guidance Book
Shabista Imam
 
Best Practice for LLM Serving in the Cloud
Best Practice for LLM Serving in the Cloud
Alluxio, Inc.
 
Best MLM Compensation Plans for Network Marketing Success in 2025
Best MLM Compensation Plans for Network Marketing Success in 2025
LETSCMS Pvt. Ltd.
 
Download Adobe Illustrator Crack free for Windows 2025?
Download Adobe Illustrator Crack free for Windows 2025?
grete1122g
 
Automated Migration of ESRI Geodatabases Using XML Control Files and FME
Automated Migration of ESRI Geodatabases Using XML Control Files and FME
Safe Software
 
Microsoft-365-Administrator-s-Guide1.pdf
Microsoft-365-Administrator-s-Guide1.pdf
mazharatknl
 
IObit Driver Booster Pro 12 Crack Latest Version Download
IObit Driver Booster Pro 12 Crack Latest Version Download
pcprocore
 
Which Hiring Management Tools Offer the Best ROI?
Which Hiring Management Tools Offer the Best ROI?
HireME
 
ERP Systems in the UAE: Driving Business Transformation with Smart Solutions
ERP Systems in the UAE: Driving Business Transformation with Smart Solutions
dheeodoo
 
How Automation in Claims Handling Streamlined Operations
How Automation in Claims Handling Streamlined Operations
Insurance Tech Services
 

Concurrency Programming in Java - 06 - Thread Synchronization, Liveness, Guarded Blocks, Immutable Objects

  • 2. Recap so far… Sachintha Gunasena MBCS http://lk.linkedin.com/in/sachinthadtg
  • 3. Previous Session • Processes & Threads • Thread Objects • Defining & Starting a Thread • Pausing Execution with Sleep • Interrupts • Joins • The Simple Threads Example • Synchronisation • Thread Interference • Memory Consistency Errors
  • 5. Today’s Session • Synchronization • Synchronised Methods • Intrinsic Locks & Synchronisation • Atomic Access • Liveness • Deadlock • Starvation & Livestock • Guarded Blocks • Immutable Objects • A Synchronized Class Example • A Strategy for Defining Immutable Objects
  • 7. Synchronized Methods • To make a method synchronized, simply add the synchronized keyword to its declaration: public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } }
  • 8. Synchronized Methods Cont.d • If count is an instance of SynchronizedCounter, then making these methods synchronized has two effects: • First, it is not possible for two invocations of synchronized methods on the same object to interleave. • 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 • Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. • This guarantees that changes to the state of the object are visible to all threads • constructors cannot be synchronized • using the synchronized keyword with a constructor is a syntax error. • because only the thread that creates an object should have access to it while it is being constructed.
  • 9. Synchronized Methods Cont.d • Warning: • When constructing an object that will be shared between threads, be very careful that a reference to the object does not "leak" prematurely. • For example, suppose you want to maintain a List called instances containing every instance of class. • You might be tempted to add the following line to your constructor: • But then other threads can use instances to access the object before construction of the object is complete. instances.add(this);
  • 10. Synchronized Methods Cont.d • Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: • if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods. • (An important exception: final fields, which cannot be modified after the object is constructed, can be safely read through non- synchronized methods, once the object is constructed) • This strategy is effective, but can present problems with liveness, as we'll see later.
  • 11. Intrinsic Locks and Synchronization • Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. • (The API specification often refers to this entity simply as a "monitor.") • Intrinsic locks play a role in both aspects of synchronization: • enforcing exclusive access to an object's state and • establishing happens-before relationships that are essential to visibility.
  • 12. Intrinsic Locks and Synchronization Cont.d • Every object has an intrinsic lock associated with it. • By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. • A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. • As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. • The other thread will block when it attempts to acquire the lock. • When a thread releases an intrinsic lock, a happens-before relationship is established between that action and any subsequent acquisition of the same lock.
  • 13. Locks In Synchronized Methods • When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. • The lock release occurs even if the return was caused by an uncaught exception. • You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. • In this case, the thread acquires the intrinsic lock for the Class object associated with the class. • Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.
  • 14. Synchronized Statements • Another way to create synchronized code is with synchronized statements. • Unlike synchronized methods, synchronized statements must specify the object that provides the intrinsic lock: public void addName(String name) { synchronized(this) { lastName = name; nameCount++; } nameList.add(name); }
  • 15. Synchronized Statements Cont.d • In this example, the addName method needs to synchronize changes to lastName and nameCount, but also needs to avoid synchronizing invocations of other objects' methods. • (Invoking other objects' methods from synchronized code can create problems that are described in the section on Liveness.) • Without synchronized statements, there would have to be a separate, unsynchronized method for the sole purpose of invoking nameList.add. • Synchronized statements are also useful for improving concurrency with fine-grained synchronization. • Suppose, for example, class MsLunch has two instance fields, c1 and c2, that are never used together. • All updates of these fields must be synchronized, but there's no reason to prevent an update of c1 from being interleaved with an update of c2 — and doing so reduces concurrency by creating unnecessary blocking. • Instead of using synchronized methods or otherwise using the lock associated with this, we create two objects solely to provide locks. • You must be absolutely sure that it really is safe to interleave access of the affected fields.
  • 16. Synchronized Statements Cont.d 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++; } } }
  • 17. Re-entrant Synchronization • Recall that a thread cannot acquire a lock owned by another thread. • But a thread can acquire a lock that it already owns. • Allowing a thread to acquire the same lock more than once enables reentrant synchronization. • This describes a situation where synchronized code, directly or indirectly, invokes a method that also contains synchronized code, and both sets of code use the same lock. • Without reentrant synchronization, synchronized code would have to take many additional precautions to avoid having a thread cause itself to block.
  • 18. Atomic Access • one that effectively happens all at once. • An atomic action cannot stop in the middle: • it either happens completely, • or it doesn't happen at all. • No side effects of an atomic action are visible until the action is complete. • We have already seen that an increment expression, such as c++, does not describe an atomic action. • Even very simple expressions can define complex actions that can decompose into other actions. • However, there are actions you can specify that are atomic: • Reads and writes are atomic for reference variables and 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)
  • 19. Atomic Access Cont.d • Atomic actions cannot be interleaved, so they can be used without fear of thread interference. • However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. • Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. • This means that changes to a volatile variable are always visible to other threads. • What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change. • Using simple atomic variable access is more efficient than accessing these variables through synchronized code, but requires more care by the programmer to avoid memory consistency errors. • Whether the extra effort is worthwhile depends on the size and complexity of the application. • Some of the classes in the java.util.concurrent package provide atomic methods that do not rely on synchronization.
  • 21. Liveness • A concurrent application's ability to execute in a timely manner is known as its liveness. • This section covers the most common kind of liveness problem, deadlock, and goes on to briefly describe two other liveness problems, starvation and livelock.
  • 22. Deadlock • a situation where two or more threads are blocked forever, waiting for each other • e.g.: • Tom and Jerry are friends, and great believers in courtesy. • A strict rule of courtesy is that when you bow to a friend, you must remain bowed until your friend has a chance to return the bow. • Unfortunately, this rule does not account for the possibility that two friends might bow to each other at the same time. • This example application, Deadlock, models this possibility: • When Deadlock runs, it's extremely likely that both threads will block when they attempt to invoke bowBack.
  • 23. Deadlock Cont.dpublic class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void bow(Friend bower) { System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName()); bower.bowBack(this); } public synchronized void bowBack(Friend bower) { System.out.format("%s: %s" + " has bowed back to me!%n", this.name, bower.getName()); } } public static void main(String[] args) { final Friend tom = new Friend("Tom"); final Friend jerry = new Friend("Jerry"); new Thread(new Runnable() { public void run() { tom.bow(jerry); } }).start(); new Thread(new Runnable() { public void run() { jerry.bow(tom); } }).start(); } }
  • 24. Deadlock Cont.d • When Deadlock runs, it's extremely likely that both threads will block when they attempt to invoke bowBack. • Neither block will ever end, because each thread is waiting for the other to exit bow.
  • 25. Starvation & Livelock • Starvation and livelock are much less common a problem than deadlock, • but are still problems that every designer of concurrent software is likely to encounter.
  • 26. Starvation • a situation where a thread is unable to gain regular access to shared resources and is unable to make progress. • This happens when shared resources are made unavailable for long periods by "greedy" threads. • For example, • suppose an object provides a synchronized method that often takes a long time to return. • If one thread invokes this method frequently, • other threads that also need frequent synchronized access to the same object will often be blocked.
  • 27. Livelock • A thread often acts in response to the action of another thread. • If the other thread's action is also a response to the action of another thread, then livelock may result. • As with deadlock, livelocked threads are unable to make further progress. • However, the threads are not blocked — they are simply too busy responding to each other to resume work. • This is comparable to two people attempting to pass each other in a corridor: • Tom moves to his left to let Jerry pass, while Jerry moves to his right to let Tom pass. • Seeing that they are still blocking each other, Tom moves to his right, while Jerry moves to his left. • They're still blocking each other, so...
  • 29. Guarded Blocks • Threads often have to coordinate their actions. • The most common coordination idiom is the guarded block. • Such a block begins by polling a condition that must be true before the block can proceed. • There are a number of steps to follow in order to do this correctly. • Suppose, for example guardedJoy is a method that must not proceed until a shared variable joy has been set by another thread. • Such a method could, • in theory, simply loop until the condition is satisfied, • but that loop is wasteful, since it executes continuously while waiting.
  • 30. Guarded Blocks Cont.d public void guardedJoy() { // Simple loop guard. Wastes // processor time. Don't do this! while(!joy) {} System.out.println("Joy has been achieved!"); }
  • 31. Guarded Blocks Cont.d • A more efficient guard invokes Object.wait to suspend the current thread. • The invocation of wait does not return until another thread has issued a notification that some special event may have occurred • — though not necessarily the event this thread is waiting for:
  • 32. Guarded Blocks Cont.d public synchronized void guardedJoy() { // This guard only loops once for each special event, which may not // be the event we're waiting for. while(!joy) { try { wait(); } catch (InterruptedException e) {} } System.out.println("Joy and efficiency have been achieved!"); }
  • 33. Guarded Blocks Cont.d • Note: • Always invoke wait inside a loop that tests for the condition being waited for. • Don't assume that • the interrupt was for the particular condition you were waiting for, • or that the condition is still true.
  • 34. Guarded Blocks Cont.d • Like many methods that suspend execution, wait can throw InterruptedException. • In this example, we can just ignore that exception — we only care about the value of joy. • Why is this version of guardedJoy synchronized? • Suppose d is the object we're using to invoke wait. • When a thread invokes d.wait, it must own the intrinsic lock for d — otherwise an error is thrown. • Invoking wait inside a synchronized method is a simple way to acquire the intrinsic lock. • When wait is invoked, the thread releases the lock and suspends execution. • At some future time, • another thread will acquire the same lock and invoke Object.notifyAll, • informing all threads waiting on that lock that something important has happened:
  • 35. Guarded Blocks Cont.d • Some time after the second thread has released the lock, • the first thread reacquires the lock and resumes • by returning from the invocation of wait. public synchronized notifyJoy() { joy = true; notifyAll(); }
  • 36. Guarded Blocks Cont.d • Note: • There is a second notification method, notify, which wakes up a single thread. • Because notify doesn't allow you to specify the thread that is woken up, • it is useful only in massively parallel applications • — that is, programs with a large number of threads, all doing similar chores. • In such an application, you don't care which thread gets woken up.
  • 37. Guarded Blocks Cont.d • Let's use guarded blocks to create a Producer-Consumer application. • This kind of application shares data between two threads: • the producer, that creates the data, • and the consumer, that does something with it. • The two threads communicate using a shared object. • Coordination is essential: • the consumer thread must not attempt to retrieve the data before the producer thread has delivered it, • and the producer thread must not attempt to deliver new data if the consumer hasn't retrieved the old data. • In this example, • the data is a series of text messages, which are shared through an object of type Drop:
  • 38. Guarded Blocks Cont.dpublic class Drop { // Message sent from producer // to consumer. private String message; // True if consumer should wait // for producer to send message, // false if producer should wait for // consumer to retrieve message. private boolean empty = true; public synchronized String take() { // Wait until message is // available. while (empty) { try { wait(); } catch (InterruptedException e) {} } // Toggle status. empty = true; // Notify producer that // status has changed. notifyAll(); return message; } public synchronized void put(String message) { // Wait until message has // been retrieved. while (!empty) { try { wait(); } catch (InterruptedException e) {} } // Toggle status. empty = false; // Store message. this.message = message; // Notify consumer that status // has changed. notifyAll(); } }
  • 39. Guarded Blocks Cont.d • The producer thread, defined in Producer, sends a series of familiar messages. • The string "DONE" indicates that all messages have been sent. • To simulate the unpredictable nature of real-world applications, • the producer thread pauses for random intervals between messages.
  • 40. Guarded Blocks Cont.d import java.util.Random; public class Producer implements Runnable { private Drop drop; public Producer(Drop drop) { this.drop = drop; } public void run() { String importantInfo[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy", "A kid will eat ivy too" }; Random random = new Random(); for (int i = 0; i < importantInfo.length; i++) { drop.put(importantInfo[i]); try { Thread.sleep(random.nextInt(5000)); } catch (InterruptedException e) {} } drop.put("DONE"); } }
  • 41. Guarded Blocks Cont.d • The consumer thread, • defined in Consumer, • simply retrieves the messages and prints them out, • until it retrieves the "DONE" string. • This thread also pauses for random intervals.
  • 42. Guarded Blocks Cont.d import java.util.Random; public class Consumer implements Runnable { private Drop drop; public Consumer(Drop drop) { this.drop = drop; } public void run() { Random random = new Random(); for (String message = drop.take(); ! message.equals("DONE"); message = drop.take()) { System.out.format("MESSAGE RECEIVED: %s%n", message); try { Thread.sleep(random.nextInt(5000)); } catch (InterruptedException e) {} } } }
  • 43. Guarded Blocks Cont.d • Finally, here is the main thread, defined in ProducerConsumerExample, that launches the producer and consumer threads. • Note: The Drop class was written in order to demonstrate guarded blocks. To avoid re-inventing the wheel, examine the existing data structures in the Java Collections Framework before trying to code your own data-sharing objects. public class ProducerConsumerExample { public static void main(String[] args) { Drop drop = new Drop(); (new Thread(new Producer(drop))).start(); (new Thread(new Consumer(drop))).start(); } }
  • 45. Immutable Objects • An object is considered immutable if its state cannot change after it is constructed. • Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code. • Immutable objects are particularly useful in concurrent applications. • Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state. • Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object as opposed to updating an object in place. • The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects. • These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption. • The following subsections take a class whose instances are mutable and derives a class with immutable instances from it. • In so doing, they give general rules for this kind of conversion and demonstrate some of the advantages of immutable objects.
  • 46. A Synchronized Class Example • The class, SynchronizedRGB, defines objects that represent colors. • Each object represents the color as three integers that stand for primary color values and a string that gives the name of the color.
  • 47. A Synchronized Class Example Cont.dpublic class SynchronizedRGB { // Values must be between 0 and 255. private int red; private int green; private int blue; private String name; private void check(int red, int green, int blue) { if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) { throw new IllegalArgumentException(); } } public SynchronizedRGB(int red, int green, int blue, String name) { check(red, green, blue); this.red = red; this.green = green; this.blue = blue; this.name = name; } public void set(int red, int green, int blue, String name) { check(red, green, blue); synchronized (this) { this.red = red; this.green = green; this.blue = blue; this.name = name; } } public synchronized int getRGB() { return ((red << 16) | (green << 8) | blue); } public synchronized String getName() { return name; } public synchronized void invert() { red = 255 - red; green = 255 - green; blue = 255 - blue; name = "Inverse of " + name; } }
  • 48. A Synchronized Class Example Cont.d • SynchronizedRGB must be used carefully to avoid being seen in an inconsistent state. • Suppose, for example, a thread executes the following code: • If another thread • invokes color.set after Statement 1 but before Statement 2, • the value of myColorInt won't match the value of myColorName. SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black"); ... int myColorInt = color.getRGB(); //Statement 1 String myColorName = color.getName(); //Statement 2
  • 49. A Synchronized Class Example Cont.d • To avoid this outcome, the two statements must be bound together: • This kind of inconsistency is only possible for mutable objects • — it will not be an issue for the immutable version of SynchronizedRGB. synchronized (color) { int myColorInt = color.getRGB(); String myColorName = color.getName(); }
  • 50. A Strategy for Defining Immutable Objects • The following rules define a simple strategy for creating immutable objects. • Not all classes documented as "immutable" follow these rules. • This does not necessarily mean the creators of these classes were sloppy • — they may have good reason for believing that instances of their classes never change after construction. • However, such strategies require sophisticated analysis and are not for beginners.
  • 51. A Strategy for Defining Immutable Objects Cont.d • Don't provide "setter" methods • — methods that modify fields or objects referred to by fields. • Make all fields final and private. • Don't allow subclasses to override methods. • The simplest way to do this is to declare the class as final. • A more sophisticated approach is to • make the constructor private and construct instances in factory methods.
  • 52. A Strategy for Defining Immutable Objects Cont.d • If the instance fields include references to mutable objects, • don't allow those objects to be changed: • Don't provide methods that modify the mutable objects. • Don't share references to the mutable objects. • Never store references to external, mutable objects passed to the constructor; • if necessary, create copies, and store references to the copies. • Similarly, create copies of your internal mutable objects when necessary • to avoid returning the originals in your methods.
  • 53. A Strategy for Defining Immutable Objects Cont.d • Applying this strategy to SynchronizedRGB results in the following steps: • There are two setter methods in this class. • The first one, set, arbitrarily transforms the object, and has no place in an immutable version of the class. • The second one, invert, can be adapted by having it create a new object instead of modifying the existing one. • All fields are already private; they are further qualified as final. • The class itself is declared final. • Only one field refers to an object, and that object is itself immutable. Therefore, no safeguards against changing the state of "contained" mutable objects are necessary. • After these changes, we have ImmutableRGB:
  • 54. A Strategy for Defining Immutable Objects Cont.d final public class ImmutableRGB { // Values must be between 0 and 255. final private int red; final private int green; final private int blue; final private String name; private void check(int red, int green, int blue) { if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) { throw new IllegalArgumentException(); } } public ImmutableRGB(int red, int green, int blue, String name) { check(red, green, blue); this.red = red; this.green = green; this.blue = blue; this.name = name; } public int getRGB() { return ((red << 16) | (green << 8) | blue); } public String getName() { return name; } public ImmutableRGB invert() { return new ImmutableRGB(255 - red, 255 - green, 255 - blue, "Inverse of " + name); } }
  • 56. Next Session • High Level Concurrency Objects Sachintha Gunasena MBCS http://lk.linkedin.com/in/sachinthadtg
  • 57. Thank you. Sachintha Gunasena MBCS http://lk.linkedin.com/in/sachinthadtg