Web Programming Course - PowerPoint PPT Presentation

1 / 62
About This Presentation
Title:

Web Programming Course

Description:

... into data[top] increment top ... the stack is empty, i.e., top=0. push1 calls to stack.push(1) ... push2 performs top //top=2. 1. 2. top. 0. 1. 2. 3 ... – PowerPoint PPT presentation

Number of Views:44
Avg rating:3.0/5.0
Slides: 63
Provided by: csHai
Category:
Tags: course | programming | top | web

less

Transcript and Presenter's Notes

Title: Web Programming Course


1
Web Programming Course
  • Lecture 5 Concurrent Programming 2

2
Why Synchronization?
  • public class Stack
  • int top0
  • int data new int10
  • public void push(int num)
  • datatopnum
  • top top 1
  • public int pop()
  • top top - 1
  • return datatop

3
Why Synchronization?
  • push() consists of 2 operations
  • store the element into datatop
  • increment top
  • If push() was started, it is supposed to be
    completed with no interrupts.
  • Consider the following example of two threads
    using push() method

4
Why Synchronization?
  • class PushThread extends Thread
  • Stack stack
  • PushThread(Stack stack, String name)
  • super(name)
  • this.stackstack
  • public void run()
  • int number
  • while (true)
  • number(int)(Math.random()100) 1
  • while (stack.isFull())
  • stack.push(number)

5
Why Synchronization?
  • class PopThread extends Thread
  • Stack stack
  • PopThread(Stack stack, String name)
  • super(name)
  • this.stackstack
  • public void run()
  • int result
  • while (true)
  • while (stack.isEmpty())
  • result stack.pop()

6
Why Synchronization?
  • public class StackDemo
  • public static void main(String args)
  • Stack stack new Stack()
  • Thread push1new PushThread(stack,"push1_Thread"
    )
  • Thread push2new PushThread(stack,"push2_Thread"
    )
  • push1.start()
  • push2.start()
  • pop1.start()
  • pop2.start()

7
Why Synchronization?
top
  • Consider a scenario
  • Initially, the stack is empty, i.e., top0
  • push1 calls to stack.push(1)
  • push2 calls to stack.push(2)
  • push1 performs data01 //top0
  • push2 performs data02 //top0
  • push1 performs top //top1
  • push2 performs top //top2

3
2
1
0
8
Race Condition
  • Race condition The situation where several
    processes access and manipulate shared data (or
    resource memory, file, stream) concurrently.
  • The final value of the shared data depends upon
    which process finishes last.
  • To prevent race conditions, concurrent processes
    must be synchronized.

9
The Critical-Section Problem
  • n running processes are competing to use the same
    shared data.
  • Each process has a code segment, called critical
    section, in which the shared data is accessed.
  • Problem ensure that when one process is
    executing its critical section, no other process
    is allowed to execute its critical section.

10
Critical-Section Problem
  • Mutual exclusion - If a process Pi is executing
    its CS, no other processes can be executing their
    CS.
  • Progress - If no process is executing its CS and
    there exist some processes that wish to enter
    their CS, then their enter will not be postponed
    indefinitely.
  • Bounded Waiting - A bound must exist on the
    number of times that other processes are allowed
    to enter their CS after a process has made a
    request to enter its CS and before that request
    is granted.

11
Critical Sections
12
Critical Sections
  • Execution of the critical section will require
    atomicity
  • Execution by one thread only
  • Either does not start or fully completes
  • If the execution has started, it will be
    completed
  • No interruptions

13
Critical Sections
  • Synchronization Methods
  • Locks
  • Semaphores
  • Monitors
  • Synchronization Problems
  • Producer-Consumer Problem
  • Bounded Buffer Problem
  • Readers-Writers Problem

14
Synchronization attempt 1
  • Process A
    Process B
  • ... ...
  • while( TRUE ) while( TRUE )
  • ... ...
  • while( o.proc B ) while( o.proc
    A )
  • lt criticalA gt lt criticalB gt
  • o.proc B o.proc A
  • ... ...
  • ... ...
  • Problem violates rule 2 (strict alteration).

15
Synchronization attempt 2
  • Process A Process B
  • ... ...
  • while( TRUE ) while( TRUE )
  • ... ...
  • while( o.pBinside ) while( o.pAinside
    )
  • o.pAinside TRUE o.pBinside TRUE
  • lt criticalA gt lt criticalB gt
  • o.pAinside FALSE o.pBinside
    FALSE
  • ... ...
  • ... ...
  • Problem violates rule 1 (interleaved
    instructions).

16
Hardware Solution
  • Synchronization solutions are based on hardware
    level operations
  • Many CPUs support atomic read-modify-write
    operations
  • TAS test-and-set (Motorola 68K)
  • CAS compare-and-swap (IBM 370 and Motorola 68K)
  • XCHG exchange (x86)

17
Hardware Solution
  • Example using test-and-set (TAS)

18
Semaphores
  • A semaphore is a synchronization variable that
    takes on non-negative integers with two atomic
    operations
  • P() while ( semaphore lt 0 )
  • //wait()
  • semaphore--
  • V() semaphore
  • //signal()
  • Semaphores are simple, yet elegant, and allow the
    solution of many problems. They are useful for
    more than just mutual exclusion.

19
Object-Oriented Semaphore
  • class Semaphore
  • private int value
  • //initialized with non-negative value
  • public Semaphore(int val) value val
  • public void down()
  • while (value lt 0 )
  • value--
  • public void up()
  • value

20
Properties of semaphores
  • Semaphores are not provided by hardware, but they
    have several attractive properties
  • Simple.
  • Single resource works with many threads.
  • Can have many different critical sections with
    different semaphores.
  • Each critical section has unique access
    semaphore.
  • Can permit multiple threads into the critical
    section at once.

21
Possible Use of Semaphores
  • Mutual exclusion initialize the semaphore to one
    simultaneous thread in CS.
  • init Semaphore mutexnew Semaphore(1)
  • 1 mutex.down()
  • 2 func()
  • 3 mutex.up()

22
Type of semaphores
  • Semaphores are usually available in two flavors
  • Binary is a semaphore with an integer value of
    0 and 1.
  • Counting is a semaphore with an integer value
    ranging between 0 and an arbitrarily large
    number.
  • Its initial value represents the number of units
    of the critical resources that are available.
  • This form is also known as a general semaphore.
  • Semaphore are considered parts of the basic
    synchronization services.

23
Implementation of semaphores
  • No existing hardware implements Up() and Down()
    operations directly.
  • Semaphores are built-up in software using
    elementary hardware synchronization primitives.
  • Naïve uni-processor solution disable interrupts.

24
Monitors
  • Although semaphores solve synchronization
    problems, they provide low-level and error-prone
    solutions.
  • A better (higher-level) solution is provided by
    the monitor
  • A mutex semaphore is associated with a shared
    resource and any piece of code that touches these
    variables is preceded by mutex.down() and
    followed by mutex.up().
  • Why not to let the compiler to do this work?

25
Monitors in Java
  • Using the synchronized keyword
  • Synchronization order
  • Gain a monitor (lock)
  • Perform the desired operation
  • Release the monitor
  • Thread can not access the CS without obtaining
    the lock

26
Synchronized Methods
  • A synchronized method locks the current object
    such that no other thread can execute inside the
    object while the method is active.
  • By locking the object, we guarantee that its
    state will remain consistent during the duration
    in which the lock on the object is held by a
    thread.
  • When the lock is released, then another thread
    can lock the object and update its state.

27
Synchronized Objects
  • Java objects are all lockable objects.
  • Every object in Java is a subtype of the Object
    class in Java.
  • The Object class implements an implicit locking
    mechanism that allows any object to be locked
    during a synchronized method or synchronized
    block
  • This provides mutual exclusion

28
Object-Level Synchronization
  • public void push(int num)
  • synchronized(this)
  • datatopnum
  • top
  • public int pop()
  • synchronized(this)
  • top--
  • return datatop

29
Method-Level Synchronization
  • public synchronized void push(int num)
  • datatopnum
  • top
  • public synchronized int pop()
  • top--
  • return datatop

30
Java Synchronization Example
t1
t2
t3
synchronized(this) ...
Note, that mutual exclusion holds between
synchronized pieces of code only!!
Object-level synchronization
31
Method-level or Object-level
  • Synchronization decreases parallelization
  • It is preferable to synchronize the critical
    sections only
  • Object-level synchronization
  • However, object-level synchronization is
    impossible for static methods
  • Synchronized static methods of a class can not be
    executed in parallel

32
Synchronization Example
class InternetBankingSystem public
static void main(String args )
Account accountObject new Account ()
Thread t1 new Thread(new MyThread(accountObje
ct)) Thread t2 new Thread(new
YourThread(accountObject)) Thread t3 new
Thread(new HerThread(accountObject))
t1.start() t2.start()
t3.start() // do some other operation
// end main()
33
Synchronization Example
class MyThread implements Runnable Account
account public MyThread (Account s)
account s public void run()
account.deposit() // end class
MyThread class YourThread implements Runnable
Account account public YourThread
(Account s) account s public void
run() account.withdraw() // end class
YourThread class HerThread implements Runnable
Account account public HerThread
(Account s) account s public void
run() account.enquire() // end class
HerThread
account (shared object)
34
Synchronization Example
  • class Account // the 'monitor'
  • int balance
  • // if 'synchronized' is removed, the outcome is
    unpredictable
  • public synchronized void deposit( )
  • // METHOD BODY balance deposit_amount
  • public synchronized void withdraw( )
  • // METHOD BODY balance - deposit_amount
  • public synchronized void enquire( )
  • // METHOD BODY display balance.

35
Synchronization Example
  • 3 methods f1(), f2() and f3() in MyClass
  • Neither 2 instances of f1() nor 2 instances of
    f2() can be executed in parallel
  • However, defining them as synchronized will not
    allow to execute f1() in parallel with f2()

36
Synchronization Example
  • Solution defining 2 different monitors
  • private static Object sync_f1 new Object()
  • private static Object sync_f2 new Object()
  • And synchronizing on these monitors
  • void f1()
  • synchronized (sync_f1)
  • ... // code of f1()
  • void f2()
  • synchronized (sync_f2)
  • ... // code of f2()

37
Synchronization Example
  • f3() can not be executed in parallel neither with
    f1() nor with f2()
  • Solution
  • void f3()
  • synchronized (sync_f1)
  • synchronized (sync_f2)
  • ...// code of f3()

38
Wait(), Notify(), and NotifyAll()
  • Synchronized methods are methods that lock the
    object on entry and unlock the object on exit.
  • The Object class implements some special methods
    for allowing a thread to
  • explicitly release the lock while in the method
  • wait for the lock for some time
  • notify other threads

39
Wait(), Notify(), and NotifyAll()
  • wait() causes a thread to wait (indefinitely or
    for some time interval), and then try to
    reacquire the lock
  • notify() signals one (defined at the run-time)
    thread to wakeup
  • notifyAll() signals all threads to wakeup and
    compete to re-acquire the lock
  • If no thread is waiting, then notify() and
    notifyAll() have no effect

40
Wait(), Notify(), and NotifyAll()
  • These methods should be used only from within
    methods holding the object lock
  • If called without holding the lock, the
    IllegalMonitorStateException is thrown
  • A waiting (or sleeping) thread can also be awoken
    if it is interrupted by another thread
  • In this case, the InterruptedException is thrown

41
Producer-Consumer Problem
  • Correct behavior is
  • Producer puts 1 value in buffer
  • Then Consumer reads it
  • And so on
  • If no concurrency control on Buffer
  • If Producer is quicker than Consumer, Consumer
    will skip 1 or more values
  • Vice versa, Consumer will read same values 2 or
    more times
  • Need to synchronize the work of Producer and
    Consumer

42
Producer-Consumer Example
  • class Producer extends Thread
  • private Buffer buf
  • private int number // id
  • public Producer(Buffer b, int n)
  • buf b number n
  • public void run()
  • for (int i 0 i lt 10 i)
  • buf.put(i)
  • System.out.println(
  • "Producer " number
  • " put " i)
  • //random sleep ...
  • class Consumer extends Thread
  • private Buffer buf
  • private int number // id
  • public Consumer(Buffer b, int n)
  • buf b number n
  • public void run()
  • int value 0
  • for (int i 0 i lt 10 i)
  • value buf.get()
  • System.out.println(
  • "Consumer " number
  • " got " value)

43
Expected Output
  • Producer 1 put 0
  • Consumer 1 got 0
  • Producer 1 put 1
  • Consumer 1 got 1
  • Producer 1 put 2
  • Consumer 1 got 2
  • Producer 1 put 3
  • Consumer 1 got 3
  • Producer 1 put 4
  • Consumer 1 got 4
  • Producer 1 put 5
  • Consumer 1 got 5
  • Producer 1 put 6
  • Consumer 1 got 6
  • Producer 1 put 7
  • Consumer 1 got 7
  • Producer 1 put 8
  • Consumer 1 got 8
  • Producer 1 put 9
  • Consumer 1 got 9

44
Synchronized Produce-Consumer
  • class Buffer
  • //shared resource
  • private int num -1 //invalid
  • public synchronized int get()
  • return num
  • public synchronized void put(int value)
  • num value

45
Synchronized Produce-Consumer
  • public class ProducerConsumerTest
  • public static void main()
  • Buffer b new Buffer()
  • Producer p1new Producer(b, 1)
  • Consumer c1new Consumer(b, 1)
  • p1.start()
  • c1.start()

46
Does it work?
  • Synchronized ensures only that
  • put() and get() cannot be invoked at exactly the
    same time (no overwriting while reading)
  • In case there are multiple producers and/or
    consumers, they queue up nicely
  • It does not ensure alternation
  • e.g. Consider a case in which Consumer calls
    get() before Producer had a chance to call put()
  • One or more times
  • We need some device for threads explicitly
    coordinating with each other!

47
Synchronized Produce-Consumer
  • public synchronized void consume()
  • while (!consumable())
  • wait() // release lock and wait for resource
  • ... //have exclusive access to resource to
    consume
  • public synchronized void produce()
  • ... //change of state must result in consumable
    condition being true
  • notifyAll() // notify all waiting threads to
    try consuming

48
Synchronized Produce-Consumer
  • class Buffer
  • private int num
  • private boolean availablefalse
  • public synchronized int get()
  • while (available false)
  • try this.wait()
  • catch(InterruptedException e)e.printStackTrac
    e()
  • available false
  • this.notifyAll()
  • return num
  • public synchronized void put(int value)
  • while (available true)
  • try this.wait()
  • catch(InterruptedException e)e.printStackTrac
    e()
  • num value
  • available true

49
Condition Variables
  • When a thread is awoken, it cannot assume that
    its condition is true, as all threads are
    potentially awoken by notifyAll()
  • One would expect that the thread can assume that
    when it awakes, the shared resource is in the
    appropriate state
  • This is not always the case

50
Condition Variables
  • Another thread could get access to the shared
    resource and modify it
  • When the thread eventually gains access to the
    lock, the shared resource can again be
    inaccessible
  • Hence, it is usually essential for threads to
    re-evaluate their guards

51
Bounded Buffer Example
public class BoundedBuffer private int
buffer private int first private int
last private int numberInBuffer 0 private
int size public BoundedBuffer(int length)
size length buffer new intsize
last 0 first 0
52
Bounded Buffer Example
public synchronized void put(int item)
throws InterruptedException while
(numberInBuffer size) wait() last
(last 1) size // modulus
numberInBuffer bufferlast item
notifyAll() public synchronized int
get() throws InterruptedException
while (numberInBuffer 0) wait() first
(first 1) size // modulus
numberInBuffer-- notifyAll() return
bufferfirst
53
Readers-Writers Problem
  • Many reader and writer threads are attempting to
    access an object storing a large data structure
  • Readers can read concurrently, as they do not
    alter the data
  • Writers require mutual exclusion over the data
    both from other writers and from readers
  • Priority is always given to waiting writers
  • As soon as a writer is available, all new readers
    will be blocked until all writers have finished

54
Readers-Writers Problem
  • Standard solution requires 4 monitor methods,
    which are used

startRead() // call object to read data
structure stopRead()
startWrite() // call object to write data
structure stopWrite()
55
Readers-Writers Problem
  • Standard solution in monitors is to have two
    condition variables OkToRead and OkToWrite
  • This cannot be directly expressed using a single
    Java monitor

public class ReadersWriters private int
readers 0 private int waitingWriters 0
private boolean writing false
56
Readers-Writers Problem
public synchronized void StartWrite()
while(readers gt 0 writing)
waitingWriters wait()
waitingWriters-- writing true
public synchronized void StopWrite()
writing false notifyAll()
loop to re-test the condition
Wakeup everyone
57
Readers-Writers Problem
public synchronized void StartRead()
throws InterruptedException while(writing
waitingWriters gt 0) wait() readers
public synchronized void StopRead()
readers-- if(readers 0) notifyAll()

58
Starvation and Deadlock
  • Starvation situation where a thread is
    continuously deferred by the scheduler
  • Deadlock situation two or more threads can not
    proceed, since they are waiting for each other

59
Deadlock Necessary Conditions
  • Mutual Exclusion
  • Each processor has exclusive use of its resources
  • Non-preemption
  • A process never releases resources until it has
    finished using them
  • Resource waiting
  • Each process holds resources while waiting for
    other processes to release theirs
  • Cycle of waiting processes
  • Each process in the cycle waits for resources
    that the next process owns and will not relinquish

60
(No Transcript)
61
Dining Philosophers Problem
  • A philosopher can
  • Think
  • Gives up the two chopsticks on right and left
  • Eat
  • Picks up the two chopsticks on right and left one
    at a time
  • If chopstick is in use, must wait until neighbor
    thinks and then picks it up

62
Dining Philosophers Problem
  • Deadlock Scenario
  • Philosopher 1 takes his right chopstick
  • Philosopher 2 takes his right chopstick
  • Philosopher 3 takes his right chopstick
  • What are the deadlock conditions in this scenario?
Write a Comment
User Comments (0)
About PowerShow.com