Java Threading & Synchronization: Prime Number Testing & Producer-Consumer Problem Study -, Study notes of Computer Science

The concepts of multithreading and synchronization in java through the lens of prime number testing and the producer-consumer problem. It covers the creation of threads using the thread class, the concept of mutual exclusion and thread synchronization, and the prevention of deadlock. The document also includes code examples and explanations of various thread states.

Typology: Study notes

Pre 2010

Uploaded on 11/08/2009

koofers-user-lke
koofers-user-lke 🇺🇸

9 documents

1 / 52

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CNT 4714: Threading Part 2 Page 1 Mark Llewellyn ©
CNT 4714: Enterprise Computing
Fall 2008
Programming Multithreaded Applications in Java
Part 2
CNT 4714: Enterprise Computing
Fall 2008
Programming Multithreaded Applications in Java
Part 2
School of Electrical Engineering and Computer Science
University of Central Florida
Instructor : Dr. Mark Llewellyn
HEC 236, 407-823-2790
http://www.cs.ucf.edu/courses/cnt4714/fall2008
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34

Partial preview of the text

Download Java Threading & Synchronization: Prime Number Testing & Producer-Consumer Problem Study - and more Study notes Computer Science in PDF only on Docsity!

CNT 4714: Threading Part 2

Page 1

Mark Llewellyn ©

CNT 4714: Enterprise Computing

Fall 2008

Programming Multithreaded Applications in Java

Part 2

CNT 4714: Enterprise Computing

Fall 2008

Programming Multithreaded Applications in Java

Part 2

School of Electrical Engineering and Computer Science

University of Central Florida

Instructor :

Dr. Mark [email protected] 236, 407-823-2790http://www.cs.ucf.edu/courses/cnt4714/fall

CNT 4714: Threading Part 2

Page 2

Mark Llewellyn ©

Threads

-^

In the previous section of notes the thread examples allinvolved threads which were unsynchronized.

None of the

threads actually needed to communicate with one anotherand they did not require access to a shared object.

-^

The threads we’ve seen so far fall into the category ofunrelated threads. These are threads which do different tasksand do not interact with one another.

-^

A slightly more complex form of threading involves threadswhich are related but unsynchronized.

In this case, multiple

threads operate on different pieces of the same data structure.An example of this type of threading is illustrated on the nextpage with a threaded program to determine if a number isprime.

CNT 4714: Threading Part 2

Page 4

Mark Llewellyn ©

//driver class to demonstrate threaded prime number testerpublic class testPrime {public static void main (String s[]) {

//number to be tested for primality is entered as a command line argument//examples: 5557 is prime, 6841 is prime, 6842 is not primelong possPrime = Long.parseLong(s[0]);

int centuries = (int) (possPrime/100) + 1;for (int i=0; i<centuries;i++) {new testRange(i*100, possPrime).start();}

}

}

Driver Class for PrimeNumber Tester

-^

This is an example of related but unsynchronized threads. In this case thethreads are related since they are each working on a piece of the samedata, but approach it from a slightly different perspective. However, theyare unsynchronized since they do not share information.

CNT 4714: Threading Part 2

Page 5

Mark Llewellyn ©

6841 is prime

2048 and 6842 are notprime – their factorsare shown by thethread whichdiscovered the factor.

CNT 4714: Threading Part 2

Page 7

Mark Llewellyn ©

// class to simulate a steam boiler to illustrate a race condition in unsynchronized threadspublic class SteamBoiler {static int pressureGauge = 0;static final int safetyLimit = 20;public static void main(String [] args) {

pressure []psi = new pressure[10];for (int i = 0; i < 10; i++) {

psi[i] = new pressure();psi[i].start(); } //we now have 10 threads in execution to monitor the pressuretry {for (int i = 0; i < 10; i++)

psi[i].join(); //wait for the thread to finish } catch (Exception e) { } //do nothingSystem.out.println("Gauge reads " + pressureGauge + ", the safe limit is 20"); } }

Class to Simulate a Steam Boiler – Pressure Gauge

CNT 4714: Threading Part 2

Page 8

Mark Llewellyn ©

Thread Class to Read Steam Boiler Pressure Gauge andIncrease the Pressure if Within Range

//thread class to raise the pressure in the Boilerclass pressure extends Thread {void RaisePressure() {if (SteamBoiler.pressureGauge < SteamBoiler.safetyLimit-15) {

//wait briefly to simulate some calculationstry {sleep(100); } catch (Exception e) { }SteamBoiler.pressureGauge+= 15; //raise the pressure 15 psiSystem.out.println("Thread " + getName() + " finds pressure within limits -

increases pressure");}

else ; //the pressure is too high - do nothing }// end RaisePressurepublic void run() {

RaisePressure(); //this thread is to raise the pressure

} }

CNT 4714: Threading Part 2

Page 10

Mark Llewellyn ©

Interesting Note on Race Conditions

-^

You may remember the large North American power blackout that occurred onAugust 14, 2003.

Roughly 50 million people lost electrical power in a region

stretching from Michigan through Canada to New York City.

It took three days

to restore service to some areas.

-^

There were several factors that contributed to the blackout, but the official reporthighlights the failure of the alarm monitoring software which was written in C++by GE Energy. The software failure wrongly led operators to believe that all waswell, and precluded them from rebalancing the power load before the blackoutcascaded out of control.

-^

Because the consequences of the software failure were so severe, the bug wasanalyzed exhaustively.

The root cause was finally identified by artificially

introducing delays in the code (just like we did in the previous example).

There

were two threads that wrote to a common data structure, and through a codingerror, they could both update it simultaneously.

It was a classic race condition,

and eventually the program “lost the race”, leaving the structure in an inconsistentstate.

That in turn caused the alarm event handler to spin in an infinite loop, instead of raising the alarm.

The largest power failure in the history of the US

and Canada was caused by a race condition bug in some threaded C++ code.Java is equally vulnerable to this kind of bug.

CNT 4714: Threading Part 2

Page 11

Mark Llewellyn ©

The Therac-25 Accidents

-^

Starting in 1976, the Therac-25 treatment system, built by Atomic Energyof Canada Limited (AECL) and COR MeV of France, was used to fightcancer by providing radiation to a specific part of the body in the hope ofdestroying tumors.

-^

Six known Therac-25 accidents have been documented, all involvedmassive overdoses of radiation and three resulted in the death of thepatient, serious long-term injury and disfigurement occurred in the othercases. Patients received an estimated 17,000 to 25,000 rads to very smallbody areas.

By comparison, doses of 1000 rads can be fatal if delivered

to the whole body.

-^

Analysis determined that the primary cause of the overdoses was faultysoftware.

The software was written in assembly language and was

developed and tested by the same person.

The software included a

scheduler and concurrency in its design. When the system was first built,operators complained that it took too long to enter the treatment plan intothe computer.

As a result, the software was modified to allow operators

to quickly enter treatment data by simply pressing the Enter key when aninput value did not require changing.

CNT 4714: Threading Part 2

Page 13

Mark Llewellyn ©

Thread Synchronization

-^

To prevent a race condition, access to the shared object mustbe properly synchronized.–

Lost update problem: one thread is in the process of updatingthe shared value and another thread also attempts to update thevalue.

-^

Even worse is when only part of the object is updated by eachthread in which case part of the object reflects informationfrom one thread while another part of the same object reflectsinformation from another thread.

-^

The problem can be solved by giving one thread at a timeexclusive access to code that manipulates the shared object.During that time, other threads desiring to manipulate theobject must be forced to wait.

CNT 4714: Threading Part 2

Page 14

Mark Llewellyn ©

Thread Synchronization

(cont.)

-^

When the thread with exclusive access to the object finishesmanipulating the object, one of the blocked threads will beallowed to proceed and access the shared object.–

The next selected thread will be based on some protocol.

The

most common of these is simply FCFS (priority-queue based).

-^

In this fashion, each thread accessing the shared objectexcludes

all

other

threads

from

accessing

the

object

simultaneously.

This is the process known as mutual

exclusion.

-^

Mutual

exclusion

allows

the

programmer

to

perform

thread

synchronization,

which

coordinates

access

to

shared objects by concurrent threads.

CNT 4714: Threading Part 2

Page 16

Mark Llewellyn ©

Synchronization Techniques

(cont.)

-^

Read/write Locks.

These are also commonly referred to as mutexes

(although

some

people

still

use

the

term

mutex

to

refer

to

a

semaphore.) A lock provides a simple ”turnstile”: only one thread ata time can be going through (executing in) a block protected by alock. Again, it is easy to build a lock from semaphores.

-^

Monitors. A monitor is a higher-level synchronization construct builtout of a lock plus a variable that keeps track of some relatedcondition, such as “the number of unconsumed bytes in the buffer”.It is easy to build monitors from read/write locks. A monitor definesseveral methods as a part of its protocol.

Two of those predefined

methods are

wait()

and

notify()

.

CNT 4714: Threading Part 2

Page 17

Mark Llewellyn ©

Types of Synchronization

-^

There

are

two

basic

types

of

synchronization

between

threads:1.^

Mutual exclusion is used to protect certain critical sections of codefrom

being

executed

simultaneously

by

two

or

more

threads.

(Synchronization without cooperation.)

2.^

Signal-wait is used when one thread need to wait until another threadhas completed some action before continuing. (Synchronization withcooperation.)

-^

Java includes mechanisms for both types of synchronization.

-^

All synchronization in Java is built around locks.
Every Java
object has an associated lock.
Using appropriate syntax, you
can specify that the lock for an object be locked when a methodis invoked. Any further attempts to call a method for the lockedobject by other threads cause those threads to be blocked untilthe lock is unlocked.

CNT 4714: Threading Part 2

Page 19

Mark Llewellyn ©

An Aside on Reentrant Locks

-^

Class

ReentrantLock

(package java.util.concurrent.locks)

is a basic implementation of the

Lock

interface.

-^

The constructor for a

ReentrantLock

takes a boolean argument

that specifies whether the lock has a fairness policy.

If this is set to

true,

the

ReentrantLock’s

fairness

policy states that the longest-

waiting thread will acquire the lock when it is available.

If set to

false, there is no guarantee as to which waiting thread will acquire thelock when it becomes available.

-^

Using a lock with a fairness policy helps avoid indefinitepostponement (starvation) but can also dramatically reducethe overall efficiency of a program. Due to the large decreasein performance, fair locks should be used only in necessarycircumstances.

CNT 4714: Threading Part 2

Page 20

Mark Llewellyn ©

Condition Variables

-^

If a thread that holds the lock on an object determines that itcannot continue with its task until some condition is satisfied,the thread can wait on a condition variable.

-^

This removes the thread from contention for the processor byplacing it in a wait queue for the condition variable andreleases the lock on the object.

-^

Condition variables must be associated with a

Lock

and are

created by invoking

Lock

method

newCondition

, which

returns an object that implements the

Condition

interface.

-^

To

wait

on

a

condition

variable,

the

thread

can

call

the

Condition

’s^

await

method (see Life Cycle of a thread in

previous set of notes).