Internet Software Development - PowerPoint PPT Presentation

1 / 37
About This Presentation
Title:

Internet Software Development

Description:

Main thread waits until other threads are complete. User gets control ready for next operation ... He waits until the collection has exceeded a certain amount ... – PowerPoint PPT presentation

Number of Views:51
Avg rating:3.0/5.0
Slides: 38
Provided by: PaulK101
Category:

less

Transcript and Presenter's Notes

Title: Internet Software Development


1
Internet Software Development
  • More stuff on Threads
  • Paul Krause

2
Lecture 12 -
  • Contents
  • Basics of threads and synchronization
  • Waiting - releasing locks
  • Collection Plate example
  • Choices when pausing execution
  • Ice Cream Example
  • Notify versus NotifyAll

3
Quick Reminder
User requests document is printed and saved
Word processor spools print job
Word processor starts saving to hard drive
User requests document is printed and saved
4
A Better Solution
Thread starts spooling print job
User requests document is printed and saved
Spawn threads to print and save
Main thread waits until other threads are complete
User gets control ready for next operation
Thread starts saving document to hard drive
5
Basic concepts
  • Synchronization enables a Java object to be
    locked for exclusive use by a thread
  • A locked object is inaccessible to any thread
    other than the one that locked it
  • So long as the other threads honour this
  • Each object can keep track of the other threads
    that want exclusive access to it
  • How to keep threads fighting over limited toys!

6
Waiting
  • This is not just a matter of notifying the JVM it
    can (but doesnt have to!) provide resource to
    other threads
  • As with Thread.yield or Thread.sleep
  • Calling myObject.wait will release myObjects
    lock
  • Waiting is the process of getting (completely)
    out of the way when you cant be productive

7
CollectionPlate example
  • Minister passes around a collection plate
  • He waits until the collection has exceeded a
    certain amount
  • While he is waiting, other people can modify the
    state of the collection plate
  • By adding money to it
  • Once the total collected exceeds a certain
    amount, the Minister takes back the plate

8
Structure of Minister Class
  • public class Minister
  • private CollectionPlate collectionPlate
  • new CollectionPlate()
  • private class CollectionAcceptor extends Thread
  • private class CollectionChecker extends Thread

9
CollectionPlate
  • We will lock the instance of CollectionPlate
    whenever we access or modify its state
  • private class CollectionPlate
  • int amount 0

10
main method
  • Start off a thread that is going to monitor the
    state of the collectionPlate
  • minister.new CollectionChecker().start()
  • Within the run method of the CollectionChecker,
    we
  • Obtain the lock on collectionPlate
  • If the amount on the collectionPlate is less than
    100 we temporarily release the lock until we are
    notified by another thread of a change

11
CollectionCheckers run()
  • synchronized (collectionPlate)
  • while (collectionPlate.amount lt
    100)
  • try
  • System.out.println("Waitin
    g")
  • collectionPlate.wait()
  • catch (InterruptedException
    ie)
  • ie.printStackTrace()
  • // getting past the while
    statement means that the
  • // contribution goal has been met
  • System.out.println("Thank you!")

12
More detail
  • The CollectionChecker must have the lock for
    collectionPlate before it calls wait() on it
  • The CollectionChecker cannot proceed if there is
    less than 100 units on the plate
  • So theCollectionChecker waits by releasing the
    lock on the collectionPlate and waiting until
    another thread notifies it of a change in state
    to the latter
  • If the amount is still lt 100 it waits some more.
    Otherwise it says Thank you and terminates

13
What happens during a wait
  • In the Minister case, several threads have been
    started up that can accept contributions
  • for (int i 0 i lt 6 i )
  • minister.new CollectionAcceptor(20).start()
  • In turn, each will claim the lock on the
    collectionPlate, add 20 and then notify the
    ministrr when it has finished

14
CollectionAcceptors run()
  • synchronized (collectionPlate)
  • int amount collectionPlate.amount
  • contribution
  • String msg "Contributing current
  • amount " amount
  • System.out.println(msg)
  • collectionPlate.amount amount
  • collectionPlate.notify()

15
The result
  • In turn (why?) each instance of
    CollectionAcceptor obtains the lock on
    collectionPlate
  • 20 is then added to the collectionPlate and the
    waiting class is notified when the lock is
    released again
  • The CollectionAcceptor (minister) can resume
    execution and check the contents of the
    collectionPlate

16
An example run
  • run-single
  • Waiting
  • Contributing current amount 20
  • Waiting
  • Contributing current amount 40
  • Waiting
  • Contributing current amount 60
  • Waiting
  • Contributing current amount 80
  • Waiting
  • Contributing current amount 100
  • Thank you!
  • Contributing current amount 120

17
In General
  • If myObject.wait() is called by threadA, then
  • threadA temporarily releases the lock on myObject
  • Execution of threadA is suspended
  • threadA registers its interest in being notified
    after another thread has modified myObject
  • Once notified, threadA can resume execution
    having recovered the lock on myObject
  • It is the designers responsibility to ensure
    waiting objects are notified

18
Pausing execution
  • Maintain current locks
  • Waiting for some event to occur, before
    completing the process of accessing or modifying
    a resource
  • Release current locks
  • Having completed business with a resource, this
    pause means the thread has finished its work for
    now

19
Other fun things with threads!
  • Yielding
  • Politely offering up your place the the queue
  • Does not release locks
  • Blocking
  • A thread will block while it is waiting for a
    lock
  • The JVM will automatically tranisition it to
    Runnable when the lock becomes available
  • Sleeping
  • Waits at least as long as the specified time

20
Ice-cream man example
  • We create a number of Children as customers of an
    IceCream man
  • Each Child has an IceCreamDish that should be
    filled completely before the IceCream man serves
    another customer
  • In the the application, the instance of
    IceCreamMan is declared static to ensure there is
    only one instance (is there another way of doing
    this?)
  • The IceCreamMans thread is set as a daemon
    thread - So?

21
Basic outline
  • Start the IceCreamMan on a new thread
  • Start three instances of Child, each on their own
    thread
  • Each child will obtain a dish of ice cream and
    eat it
  • Once all three children have eaten their ice
    cream, the main thread prints out a message and
    terminates
  • What about iceCreamMan?

22
Starting the iceCreamMan
  • Remember iceCreamMan new IceCreamMan() is a
    static property of Chil\
  • Hence (as far as Children are concerned) there is
    only one iceCreamMan
  • In the main method
  • iceCreamMan.setDaemon(true)
  • iceCreamMan.start()

23
Getting the children going
  • String names "Ricardo", "Paolo", "Maria"
  • Thread children new Threadnames.length
  • // create some child objects
  • // create a thread for each child
  • // get the Child threads started
  • int counter -1
  • for (String name names)
  • Child child new Child(name)
  • childrencounter new Thread(child)
  • childrencounter.start()

24
Whats the iceCreamMan doing?
  • The iceCreamMan has a list of IceCreamDishes
  • private ListltIceCreamDishgt dishes
  • new ArrayListltIceCreamDishgt ()
  • If the list is not empty, he serves some ice
    cream, otherwise he sleeps for a bit to give the
    children a chance to add dishes

25
iceCreamMan.run()
  • public void run()
  • while (true)
  • if (!dishes.isEmpty())
  • serveIceCream()
  • else
  • try
  • sleep(1000)
  • catch(InterruptedException ie)
  • ie.printStackTrace()

26
The story so far
  • The iceCreamMan is waiting for some dishes to
    fill
  • Three children have been started, so what are
    they doing?
  • Child.run()
  • // add myDish to iceCreamMan.dishes
  • iceCreamMan.requestIceCream(myDish)
  • // now try to eat myDish of ice cream
  • eatIceCream()

27
Eating iceCream
  • public void eatIceCream()
  • synchronized(myDish)
  • while (myDish.readyToEat false)
  • try
  • System.out.println(name msg)
  • myDish.wait()
  • catch (InterruptedException ie)
  • ie.printStackTrace()
  • myDish.readyToEat false
  • System.out.println(name " yum")

28
So?
  • The Child owns the lock on its iceCreamDish
  • If the iceCreamDish is not ready to eat, the
    Child releases the lock and waits to be notified
    when it is full
  • Note the use of a while loop, and not an if
    statement.
  • It is possible that the Child thread could wake
    up before it is notified. By using a while loop,
    the guard will be checked again if such a
    spurious wake up occurs

29
IceCreamMan.serveIceCream
  • private void serveIceCream()
  • // get an ice cream dish
  • IceCreamDish currentDish dishes.get(0)
  • synchronized (currentDish)
  • currentDish.readyToEat true
  • // notify the dish's owner that the dish is
    ready
  • currentDish.notify()
  • // remove the dish from the queue of dishes
  • dishes.remove(currentDish)

30
Note
  • Correct functioning requires both the writer of
    Child and the writer of IceCreamMan to
    synchronise on IceCreamDishes.
  • There is nothing here that forces a Child to
    synchronize.
  • But if she doesnt, then she may get a half-full
    or even empty IceCreamDish

31
notify() vs. notifyAll()
  • In the previous examples, we only had one thread
    waiting for the lock on an object at a time
  • We used notify() to inform the JVM that when lock
    was available and the waiting thread could resume
  • In general, there could be several threads
    waiting
  • notifyAll() might be more appropriate

32
More in wait()
  • Following a wait(myObject) invocation
  • The current thread is blocked
  • Unless the current thread has been interrupted,
    in which case the method exits throwing an
    InterruptedException.
  • The thread is placed in an internal wait set
    associated with myObject
  • The lock on myObject is released
  • But all other locks are retained

33
notify()
  • Following a myObject.notify() invocation
  • If one exists, then an arbitrarily chosen thread
    T is removed from the wait set associated with
    myObject
  • T must re-obtain the lock on myObject
  • It will be blocked until it does so
  • T will then resume from the point of its wait

34
myObject.notifyAll()
  • All threads in the wait set for myObject are
    removed
  • But they must wait in turn for the
    synchronization lock on myObject
  • So they will continue one at a time (at least
    until each respective thread releases the lock)

35
NotifyVersusNotifyAll.java
  • We will run the program first using notify() in
    the main method and then again using notifyAll()

36
Usage guidelines
  • Only use notify() if you are sure that the thread
    that will be notified will be able to use the
    notification
  • Note that in general you will not know which
    thread will be notified by the JVM
  • If multiple threads are waiting on one event, but
    with different conditions to meet, then best to
    use notifyAll()

37
Simple example
  • Producer thread
  • synchronized(lock)
  • value Math.random()
  • lock.notifyAll()
  • Consumer Thread 1
  • synchronized(lock)
  • While (value lt 0.5) lock.wait()
  • Consumer Thread 2
  • synchronized(lock)
  • While (value gt 0.5) lock.wait()
Write a Comment
User Comments (0)
About PowerShow.com