Light-weight Threads - PowerPoint PPT Presentation

1 / 48
About This Presentation
Title:

Light-weight Threads

Description:

none – PowerPoint PPT presentation

Number of Views:22
Avg rating:3.0/5.0
Slides: 49
Provided by: raymond89
Category:
Tags: light | threads | weight

less

Transcript and Presenter's Notes

Title: Light-weight Threads


1
Threads
Download as Power Point file for saving or
printing.
2
Threads Overview
  • A thread is an execution.
  • All programs have at least one thread of
    execution control.
  • Java supports additional multiple, light-weight
    threads of execution.
  • Running two separate programs at the same time is
    an example of a heavy-weight threads, each is a
    single program in execution, the internal
    environments of other heavy-weight threads are
    isolated from one another.
  • A heavy-weight program thread can have multiple
    light-weight threads, each being switched to
    execute for a time then suspended while another
    thread executes.
  • The prime distinction between heavy and light
    weight threads are that light threads share a
    portion of a common environment where
    heavy-weight threads are isolated.
  • When light-weight threads are switched to allow
    one to execute there is less individual thread
    information to store and switch since much is
    common to all.

3
Thread Comparison
Execute one heavy thread.
Execute heavy and light thread.
public class one public static void
main(String args) new two()
System.out.println("heavy one")
class two implements Runnable public
two() new Thread(this).start()
public void run() System.out.println(
"light two")
public class one public static void
main(String args) System.out.println(h
eavy one")
Runnable
two
4
Java thread support
  • The key advantages of Java thread support are
  • communication between threads is relatively
    simple
  • inexpensive in execution since light-weight, not
    necessary to save the entire program state when
    switching between threads
  • part of language, allows a program to handle
    multiple, concurrent operations in an operating
    system platform independent fashion.
  • Java on Windows 95/98/2000/XP and other
    preemptive operating systems ensure that all
    threads will get to execute occasionally by
    preempting thread execution (stopping the
    currently executing thread and running another)
    but this does not ensure that threads execute in
    any particular order.

5
Thread Execution
  1. public class one
  2. public static void main(String args)
  3. new two()
  4. System.out.println("heavy one")
  5. class two implements Runnable
  6. public two()
  7. new Thread(this).start()
  8. public void run()
  9. System.out.println("light two")
  • Line 5 creates new two object.
  • Line 14 creates new Thread object.
  • Line 14 calls start() which calls run()and
    returns immediately.
  • Line 19 run()completes execution but does not
    return.
  • Possible execution sequences
  • 5, 14, 6, 18
  • 5, 14, 18, 6

Runnable
two run()
6
A Single Heavy-Weight Thread
  • We'll use a bouncing ball (number) to illustrate
    differences in multi-threaded execution.
  • Our thread example uses a single heavy weight
    thread to bounce a single ball off the sides of
    the display window.
  • The Ball class implements the ball bouncing,
    since a single thread is used, only one ball can
    be bounced at a time. The Ball class implements
    two public methods
  • Ball() - constructs a Ball object.
  • move() - moves a Ball a predefined distance in
    the current direction and changes direction to a
    complementary angle if a wall is encountered.
  • Try it.

7
A Single Heavy-Weight Thread
  • Only one thread is running. The key part of the
    program is
  • public void run()
  • for (int i 1 i lt 1000 i)
  • move()
  • try Thread.sleep(10) catch(Exception e)
  • invoked once as a normal function call from
    onClick( ) function by clicking the Toss button.
    The button click
  • executes the run() method
  • the ball is moved ( move is inherited from the
    Ball class),
  • the iteration in run() moves the ball
  • Thread.sleep(10) puts the main, heavy weight
    thread to sleep for at least 10 milliseconds
    giving up the CPU allowing other threads to run.
  • With 1000 iterations (each sleeping 10
    milliseconds), the ball moves for at least 10
    seconds.

8
Exercise 1
  1. public class SingleThread extends UserInterface
  2. public SingleThread() addButton("Toss")
  3. public void onClick(char c)
  4. OneThread ot new OneThread(this)
  5. ot.run()
  6. class OneThread extends Ball
  7. public OneThread(UserInterface ui)
  8. super(ui)
  9. public void run()
  10. for (int i 1 i lt 1000 i)
  11. move()
  12. try Thread.sleep(10) catch(Exception e)
  • Exercise 1
  • List in order line(s) executed when Toss button
    is clicked.
  • How many threads execute?

Ball
SingleThread
OneThread
9
Multiple Light-Weight Threads
  • With only minor changes to the previous example,
    multiple light-weight threads can support many
    simultaneously bouncing balls. Key changes are
  • Implement the Runnable class for light weight
    threads.
  • Extend OneThread class to start a new thread for
    each ball constructed when Toss clicked.
  • class MultiThread extends OneThread implements
    Runnable
  • public MultiThread(UserInterface ui)
  • super(ui)
  • new Thread(this).start()
  • Try it.

Ball move()
OneThread run()
Runnable
MultiThread
10
Runnable interface
Ball move()
OneThread run()
  • MultiThread subclass of OneThread and Runnable
  • class MultiThread extends OneThread
    implements Runnable
  • implements Runnable contract to implement method
    definition
  • public void run()
  • Thread constructed by new Thread(this)
  • run() invoked by start()
  • start() starts a thread and returns immediately
  • new Thread(this).start() constructs and starts a
    new thread.
  • Thread.sleep(10) causes a thread to give up the
    CPU.

Runnable
MultiThread
11
Multiple Threads Exercise 2
  1. public class Example extends UserInterface
  2. public Example()
  3. addButton("Toss")
  4. public void onClick(char c)
  5. MultiThread mt new MultiThread(this)
  6. class MultiThread extends OneThread
    implements Runnable
  7. public MultiThread(UserInterface ui)
  8. super(ui)
  9. new Thread(this).start()

Example run run
  1. Where is the run() method?
  2. List the lines executed when Toss is clicked the
    first time. See next slide.
  3. What happens to a thread at the end of the run( )
    method?
  4. What does new Thread(this).start( ) do, since you
    can press Toss repeatedly and another ball starts
    bouncing?

12
Multiple Threads
  1. public class Example extends UserInterface
  2. public Example()
  3. addButton("Toss")
  4. public void onClick(char c)
  5. MultiThread mt new MultiThread(this)
  6. class MultiThread extends OneThread implements
    Runnable
  7. public MultiThread(UserInterface ui)
  8. super(ui)
  9. new Thread(this).start()
  10. class OneThread extends Ball
  11. public OneThread(UserInterface ui)
  12. super(ui)
  13. public void run()

Ball move()
OneThread run()
Runnable
MultiThread
13
Execution Non-deterministic
4 Executions gtjava ST 2 1 3 4 gtjava ST 2 1 3 4 gt
java ST 1 3 2 4 gt java ST 1 2 4 3
  1. class ST
  2. public static void main(String args)
  3. new Simple(1)
  4. new Simple(2)
  5. new Simple(3)
  6. new Simple(4)
  7. class Simple implements Runnable
  8. int n
  9. Simple(int n)
  10. this.n n
  11. new Thread(this).start()
  12. public void run()
  13. try Thread.sleep(10)
  14. catch(Exception e)

14
Array of Threads
A thread is an object that can be stored in any
data structure.
  • class AT
  • public static void main(String args)
  • Simple sa new Simple10
  • for (int i0 ilt10 i) sa i new Simple(
    i )
  • class Simple implements Runnable
  • int n
  • Simple(int n)
  • this.n n
  • new Thread(this).start()
  • public void run()
  • try Thread.sleep(10) catch(Exception e)
  • System.out.print ( n )

3 Executions gtjava AT 0123456897 gt java
AT 0132547698 gtjava AT 1204365789
15
Array of Greedy Threads
  • Threads naturally run asynchronously to one
    another with no cooperation.
  • Only one thread executes at a time on the CPU
  • Race conditions can develop as multiple threads
    attempt to occupy the CPU exclusively
  • Example of many threads racing to complete
  • Only significant changes are
  • 10 threads started without artificial delay.
  • No artificial delay introduced through the
    Thread.sleep(10)
  • Try it.

16
Greedy Threads Exercise 3
  1. public class ArrayOfGreedyThreads extends
    UserInterface
  2. public ArrayOfGreedyThreads()
    addButton("Toss")
  3. public void onClick(char c)
  4. GreedyThread gt new GreedyThread10
  5. for(int i0ilt10i)
  6. gti new GreedyThread(this)
  7. class GreedyThread extends Greedy
  8. implements Runnable
  9. public GreedyThread(UserInterface ui)
  10. super(ui)
  11. new Thread(this).start()
  12. class Greedy extends Ball
  13. public Greedy (UserInterface ui)

Exercise 3 What sequence of line(s) are executed
when Toss is clicked (note for statements in
onClick() and run() methods)?
17
Thread Race
Threads compete for the CPU. Below, no thread is
able to complete before another obtains the CPU.
  • class Race
  • public static void main(String args)
  • new Simple("A") new Simple("B")
  • for (int i1 ilt5 i)
  • System.out.println("main " i)
  • class Simple implements Runnable
  • String name
  • Simple(String name)
  • this.name name
  • new Thread(this).start()
  • public void run()
  • for (int i1 ilt5 i)
  • System.out.println( name" "i ) try
    Thread.sleep(10)
  • catch(Exception e)

Threaded Execution main 1 B 1 A 1 main 2 B 2 A
2 B 3 A 3 main 3 B 4 A 4 B 5 main 4 A 5 main 5
Sequential Execution A 1A 2A 3A 4A 5B 1 B
2 B 3 B 4 B 5 main 1 main 2 main 3 main 4 main 5
18
Thread Race Conditions
  • Threads compete for execution time
  • Scheduled for execution non-deterministically
    (i.e. order of execution is not predetermined).
  • Unless thread execution completes, the thread is
    suspended and another thread given the CPU
  • Threads can execute independently
  • Race conditions occur when two or more threads
    interfere with other threads results.
  • Example illustrates how thread execution is
    arbitrary suspended by the run time system.
  • Executing the example produces differences in
    printed results.
  • Try it.

19
Race Output
  • There are 3 threads
  • ABrace in onClick()
  • A
  • B
  • Note the far right column
  • The threads a racing each other to execute

20
Thread Race Conditions Exercise 4
public class ABrace extends UserInterface
public ABrace() addButton("Start")
addButton("Clear") public void init()
Display.initialize(this) public void
onClick(char c) Race A, B switch(c)
case 'S' Display.heading(30) A new
Race("A") B new Race("B") for
(int i1 ilt5 i) Display.println("onCl
ick "i) break case 'C'
Display.clear() class Race
implements Runnable String name public
Race( String name ) this.name name
new Thread(this).start() public void
run() for (int i1 ilt5 i)
Display.println(name ""i)
  • Exercise 4
  • Execute the program several times. 
  • How many threads are executing? Explain how you
    know.
  • Can the results of 5 executions be identical?
    Explain.

21
Synchronized Threads
  • Thread execution can be
  • independent of other threads (i.e. parallel or
    asynchronous execution)
  • dependent (i.e. serialized or synchronous
    execution) where one thread executes to the
    exclusion of the other threads
  • Thread execution is controlled in Java using the
    synchronized statement which limits execution to
    a single thread.
  • The synchronization mechanism used by Java is
    termed a monitor (versus a semaphore, task, or
    other mechanism)
  • A monitor allows only one thread to have access
    to an object at a time.
  • The keyword synchronized defines a statement or
    method where one thread at a time has exclusive
    access to the object.

22
Race
  1. class RT
  2. public static void main(String args)
  3. new Racer(1)
  4. new Racer(2)
  5. new Racer(3)
  6. new Racer(4)
  7. class Racer implements Runnable
  8. int n
  9. Racer(int n)
  10. this.n n
  11. new Thread(this).start()
  12. public void run()
  13. System.out.print( "" n )
  14. try Thread.sleep(10)

gtjava RT 12341 3 2 4 gtjava
RT 12344 3 1 2 gtjava RT 13242 1 3
4
23
Non-cooperating Synchronized Example
  1. class ST
  2. public static void main(String args)
  3. new Racer(1)
  4. new Racer(2)
  5. new Racer(3)
  6. new Racer(4)
  7. class Racer implements Runnable
  8. static String commoncommon
  9. int n
  10. Racer(int n)
  11. this.n n
  12. new Thread(this).start()
  13. public void run()
  14. synchronized( common )
  15. System.out.print( "" n )
  16. try Thread.sleep(10)

gtjava ST C\d 11 22 44 33 gtjava
ST 11 33 22 44
24
Example
  • In the example above the object common is
    accessible to the threads 1, 2, 3 and 4.
  • In the run method access to common is
    synchronized so that only one thread can execute
    the code block
  • class Racer implements Runnable
  • static String commoncommon
  • int n
  • public void run()
  • synchronized( common )

System.out.print( "" n ) try
Thread.sleep(10) catch(Exception e)
System.out.println( n " )
25
Example
  • In the example below the object common is
    accessible to the two threads A and B.
  • In the run method, access to common is
    synchronized so that only one thread can execute
    the code block
  • public void run()
  • synchronized(common)
  • for (int i1 ilt5 i)
  • Display.println(name ""i)

26
Synchronized Results
  • Thread A or B will have exclusive access to
    synchronized area of run()
  • The output shows that once thread A or B enters
    the synchronized area, the other will not enter
  • The ABsynchRace thread in onClick() is not
    synchronized.
  • Try it.

27
Synchronized Threads Exercise 5
public class ABsynchRace extends UserInterface
public void onClick(char c)
SynchRace A, B String common "common"
switch(c) case 'S' A
new SynchRace("A", common) B new
SynchRace("B", common) for (int i1
ilt5 i) Display.println("onClick
"i) break case 'C'
Display.clear()
28
Synchronized Threads Exercise 5
class SynchRace implements Runnable String
name String common public SynchRace(String
name, String common ) this.name name
this.common common new
Thread(this).start() public void run()
synchronized(common) for (int i1
ilt5 i) Display.println(name ""i)
  • Exercise 5
  • How does execution differ from the unsynchronized
    version?
  • What effect does the synchronized construct
    produce?
  • How can the printing in onClick( ) be
    synchronized?
  • What would be an example of unexpected results?

29
Non-Cooperating Threads
  • Example of three independent threads
  • the main heavy-weight
  • Producer that puts onto a common queue
  • Consumer that gets from the common queue
  • Consumer thread may get from the queue before the
    Producer thread puts onto the queue
  • Any thread execution may be preempted at any time
  • No guarantee a put or get finished before another
    thread runs
  • Most obvious when the printed output is
    intermixed as in
  • put 1 get0 rather than
  • put 1 get 0
  • Try it.

30
Non-Cooperating Threads
  • put and get output intermixed, one not completed
    before other starts
  • Need synchronized access to queue object
  • Even worse, get executed when queue is empty
  • Need to force get execution to wait when queue is
    empty

31
Exercise 6
  • The Producer and Consumer are both threads, each
    having a run( ) method. Starting in the run( ) of
    each, list the sequence of lines executed that
    would print             
  • put 1get0
  • Again, starting in the run( ) of each thread,
    list the sequence that would print     get-1
    put 0    
  1. public class ProducerConsumer extends
    UserInterface
  2. public void onClick(char c)
  3. switch(c)
  4. case 'S' Q q new Q( )
  5. new Consumer(q)
  6. new Producer(q)
  7. break
  8. case 'C' Display.clear()
  9. class Q
  10. int n 0
  11. void put()
  12. n n 1
  13. Display.print("put " n)
  14. Display.println("")
  1. class Producer extends Thread
  2. Q q
  3. Producer( Q q )
  4. this.q q
  5. new Thread(this).start()
  6. public void run()
  7. for (int i1 ilt10 i)
  8. q.put() // Produce
  9. class Consumer extends Thread
  10. Q q
  11. Consumer( Q q )
  12. this.q q
  13. new Thread(this).start()
  14. public void run()

32
Unsynchronized Queue
  • public class ProducerConsumer extends
    UserInterface
  • public void onClick(char c)
  • switch(c)
  • case 'S' Q q new Q( )
  • new Consumer(q)
  • new Producer(q)
  • break
  • case 'C' Display.clear()
  • class Q
  • int n 0
  • void put()
  • n n 1
  • Display.print("put " n)
    Display.println("")
  • void get()

Producer q
Q
Consumer q
33
Producer Consumer
  1. class Producer extends Thread
  2. Q q
  3. Producer( Q q )
  4. this.q q
  5. new Thread(this).start()
  6. public void run()
  7. for (int i1 ilt10 i) q.put() //
    Produce
  8. class Consumer extends Thread
  9. Q q
  10. Consumer( Q q )
  11. this.q q
  12. new Thread(this).start()
  13. public void run()
  14. for (int i1 ilt10 i) q.get() //
    Consume

Producer q
Q
Consumer q
34
Monitors - Synchronized Producer Consumer
  • Threads interact when simultaneously accessing
    common resource.
  • Java supports a control mechanism called a
    monitor that allows only one thread at a time to
    execute a synchronized method on an object.
  • By adding synchronized to methods, a thread
    entering such a method has exclusive access to
    that object in synchronized class methods.
  • When a synchronized method completes, other
    threads may enter.
  • For a queue object, the synchronized put and get
    method ensures either completes before another
    thread enters either, for an object.
  • With two queue objects, one thread could have
    access to one queue object while another thread
    accessed the other queue object.
  • This does not ensure that something has been put
    into the queue before a thread attempts to get
    it, that is another problem.
  • Beyond cosmetics, the only change is the addition
    of
  • synchronized void put( ) synchronized void
    get( )
  • Try it

35
Monitor Behavior
  • Monitor controls access to a synchronized object.
  • Monitor allows only one thread to access object
    all other threads are blocked.
  • When thread exits synchronized method other
    threads can access synchronized object.
  • Blocked threads are automatically allowed to
    attempt to access synchronized object again.
  • Threads can still access object through
    unsynchronized methods.
  • Methods are not synchronized, objects are.
  • No conflict when threads access different objects.

36
Monitor
  • class Q
  • int n 0
  • synchronized void put( )
  • n n 1
  • Display.print("put " n)
  • Display.println("")
  • synchronized void get( )
  • n n - 1
  • Display.print("get " n)
  • Display.println("")
  • Producer p new Producer(q)
  • q.put()
  • Consumer c new Consumer(q)

Producer q
Q
Consumer q
Entered
Producer using q
Q
Consumer blocked for q
Consumer blocked when common Q object in use by
Producer
37
Synchronized Queue
  1. class Q
  2. int n 0
  3. synchronized void put( )
  4. n n 1
  5. Display.print("put " n)
  6. Display.println("")
  7. synchronized void get( )
  8. n n - 1
  9. Display.print("get " n)
  10. Display.println("")
  • Exercise 7
  • Only one thread executes any synchronized method
    on a single object. Assume Consumer thread is
    executing Line 9 when Producer thread executes
    Line 3 list the lines then executed in the
    above.
  • Is synchronizing the get method but not the put
    method sufficient to prevent intermixed output?
  • Are there still problems between the Consumer and
    Producer?

38
wait, notify and notifyAll
  • wait suspends thread until notify or notifyAll
    executed by another thread
  • notify sends signal to one waiting thread
  • Which thread notified is non-deterministic
  • notifyAll sends signal to all waiting threads
  • Only one notified thread can execute any
    synchronized method on an object at a time
  • A notified thread continues from point where wait
    executed
  • Thread enters a dead state when run completes
  • The monitor controls access to a synchronized
    object
  • No conflict when threads access different objects

39
Monitor Behavior
  • Monitor controls access to synchronized object.
  • Difference between threads blocked because
    monitor busy with another thread and threads that
    explicitly called wait
  • When synchronized method completes, blocked
    threads automatically can re-attempt object
    access
  • Threads that called wait can only proceed by
    another thread calling notify or notifyAll
  • Try it

40
Monitor
  • class Q
  • int n 0
  • synchronized void put( )
  • n n 1
  • Display.print("put" n)
  • Display.println("")
  • notify( )
  • synchronized void get( )
  • while ( n0 )
  • try wait()
  • catch (Exception e)
  • n n - 1
  • Display.print("get " n)
  • Display.println("")
  • notify( )
  1. Consumer enters get.
  2. Consumer places itself on wait.
  3. Producer enters put.
  4. Producer sends notify().
  5. Consumer released from wait.

Producer using q
Q
Consumer waits for q
Consumer waits when n0
41
Cooperating Producer Consumer
  1. class Q
  2. int n 0
  3. synchronized void put( )
  4. n n 1
  5. Display.print("put " n)
  6. Display.println("")
  7. notify( )
  8. synchronized void get( )
  9. while ( n0 )
  10. try wait()
  11. catch (Exception e)
  12. n n - 1
  13. Display.print("get " n)
  14. Display.println("")
  15. notify( )
  • wait() suspends thread until notify() executed
    by another thread
  • notify( ) sends signal to waiting thread
  • Continues from point where wait() executed.
  • Exercise 8
  • while ( n0 ) is needed. Why?
  • What happens without line 7?
  • Without line 17?

42
Cooperating Producer Consumer Busy Wait
  1. class Q
  2. int n 0
  3. synchronized void put( )
  4. n n 1
  5. Display.print("put " n)
  6. Display.println("")
  7. synchronized void get( )
  8. while ( n0 )
  9. n n - 1
  10. Display.print("get " n)
  11. Display.println("")

Exercise 8 3. Line 17 not needed.
  • Exercise 9
  • This seems to prevent consuming before producing.
    How?
  • What is the problem?

43
Multiple inheritance Thread class versus
Runnable interface
  • class MultiThread extends OneThread
    implements Runnable
  • At the start of our thread discussion we had a
    class OneThread that bounced a one ball around
    the screen. To bounce lots of balls we needed a
    class just like OneThread but that also supported
    threads.
  • We could rework OneThread to do threads but
    better solution is to inherit from OneThread to
    bounce Balls, and a thread class multiple
    inheritance.
  • Java does not directly support multiple
    inheritance.
  • Java solution is interface.
  • Class MultiThread is a subclass of Thread by
    implementing Runnable.
  • Implementing Runnable requires that class
    MultiThread must define method public void
    run()
  • Thread class implements Runnable.

44
Examples Thread and Runnable
public class example public static void
main(String args) new Simple()
class Simple implements Runnable public
Simple() new Thread(this).start()
public void run()
System.out.println("Simple")
A simple example illustrates the syntactic
differences between implementing Runnable versus
inheriting Thread. Thread inheritance is simpler
to use but prohibits other inheritance. Runnable
allows inheritance (and implementing other
interfaces) but is a little more
complicated. Both require a method public void
run()
public class example public static void
main(String args) new Simple().start()
class Simple extends Thread
public void run() System.out.println("Simp
le")
45
Deadlock
  • Deadlock occurs when one thread cannot complete.
  • One example is deadly embrace (or circular wait)
    where two threads each hold a resource required
    by the other.
  • t1 and t2 threads require both resources r1 and
    r2 to complete.
  • t1 thread holds r1 resource t2 thread holds r2
    resource.
  • t1 and t2 both deadlocked.

r2
t1
r1
t2
46
Deadlock
  • t1,t2,t3, t4 Execute synchronized method on
    common object.
  • t1 executes wait()
  • t3, t4 blocked while t2 holds object.
  • notify() not executed.
  • t1 never completes.

t3 t4
Blocked
object
t2
Wait list
t1
47
Deadlock Exercise 9
  1. waitObject wo new waitObject()
  2. for(int i0ilt10i) new ExampleThread( wo )
  3. class ExampleThread extends Thread
  4. waitObject wo
  5. ExampleThread( waitObject wo )
  6. this.wo wo
  7. new Thread(this).start()
  8. public void run()
  9. wo.exit()
  10. wo.enter()
  11. class waitObject
  12. synchronized void enter( )
  13. System.out.println("enter")
  14. notify( )
  • This always deadlocks. Why?
  • Changing to the following still deadlocks. Why?
  • public void run()
  • wo.enter()
  • wo.exit()
  • Would notify() at line 22 prevent deadlock?
    notifyAll()?

48
Multi-thread Summary
  • Thread creation - Extend Thread class or
    implement Runnable interface
  • Serialization Monitor automatically limits
    execution of synchronized method on a shared
    object to one thread
  • Basic thread control
  • Wait Places a thread on wait list for object.
  • Notify Releases an arbitrary thread from wait
    list for object.
  • NotifyAll Releases all threads from wait list
    for object.
  • Sleep Suspends thread execution for a minimum
    specified time.
Write a Comment
User Comments (0)
About PowerShow.com