M9 - Concurrency

Embed Size (px)

Citation preview

  • 8/10/2019 M9 - Concurrency

    1/40

    Java

    Module 9Concurrency

  • 8/10/2019 M9 - Concurrency

    2/40

    2

    Module Objectives

    At the end of this module, participants will beable to:

    Define the concept behind multi-threaded

    applications

    Create and control a multi-threaded application

  • 8/10/2019 M9 - Concurrency

    3/40

    3

    What is a Thread?

    The term thread is short for thread of execution. A thread of execution is a sequence of instructions that is

    executed one after another in its own call stack.

    A thread executes instructions one at a time; the thread must

    execute and finish the current instruction before moving on to

    the next one.

    From a developers perspective an application begins with 1

    main thread that is usually started when thepublic static void

    main(String[]) method is called.

  • 8/10/2019 M9 - Concurrency

    4/40

    4

    Statements are executed one at a time in the appropriatesequence depending on program flow.

    One statement must finish execution before the next

    statement can begin execution.

    ** Refer to SingleThreadWorker.java sample code

    Single Thread Application (Diagram)

    Worker

    Curly

    Created

    Worker

    Larry

    Created

    Worker

    Moe

    Created

    Main

    Thread

    Ends

    Application

    Starts

    Application

    Ends

    Main

    Thread

    Starts

    Application Timeline

    Worker

    Curly

    work(5)

    Worker

    Larry

    work(5)

    Worker

    Moe

    work(5)

  • 8/10/2019 M9 - Concurrency

    5/40

    5

    Concurrency

    An application that is able to manage and coordinate multipletasks simultaneously or pseudo-simultaneously is called a

    concurrent application.

    Concurrency allows tasks to execute without waiting for the

    other tasks to complete through a defined system of task

    switching and scheduling.

    A concurrent application is able to make better of use system

    resources as it allows a tasks to make use of a resource that

    may not be currently required by other tasks.

  • 8/10/2019 M9 - Concurrency

    6/40

    6

    Concurrency in Java

    The most common way of implementing concurrency in a Javaapplication is through multiple threads.

    Java by nature is multithreaded as all applications have several

    background threads running in addition to the application code.

    Each thread can create and start new threads.

    The application terminates when the main thread and all

    application created threads finish execution.

  • 8/10/2019 M9 - Concurrency

    7/407

    Task Scheduling

    Multiple threaded applications make use of thread switching andscheduling that allow multiple threads to make use of the

    systems resources.

    The actual algorithm for thread scheduling depends heavily on

    the native operating system.

  • 8/10/2019 M9 - Concurrency

    8/408

    Creating a Thread

    An instance of the Thread class is needed to create and executethe new thread.

    The code that the thread will execute can be defined through

    either of the following:

    Subclass the Thread class, override its public void run() method

    Pass a Runnable object with an overridden public void run() method

    to a Thread objects constructor

    Call the Thread instances start() method to start the thread.

    The code inside the run() method will be executed in its own

    thread only if it is invoked using the start() method.

  • 8/10/2019 M9 - Concurrency

    9/409

    When each MultiThreadWorker is started, it is executed in its ownthread, independent of the main thread.

    This application has a total of 4 application threads: the main thread,

    Curly thread, Larry thread and Moe thread.

    ** Refer to the MultiThreadWorker.java and MultiThreadLauncher.java sample code

    Concurrency in Java (Diagram)

    Curly

    Starts

    Larry

    Starts

    Moe

    Starts

    Main Thread

    Ends

    Moe

    Ends

    Application

    Starts

    Application

    Ends

    Main Thread

    Starts

    Curly

    Ends

    Curly works()

    Larry works()

    Moe works()

    Application Life Time

    Larry

    Ends

  • 8/10/2019 M9 - Concurrency

    10/40

    10

    When a thread is created (but not started) it is at its create state.

    When a thread invokes its start() method, it is now alive and is

    placed in a runnable poolwhere all living threads wait their turn

    to be run by the scheduler.

    Thread Lifecycle

    start()

    New

    New Runnable

  • 8/10/2019 M9 - Concurrency

    11/40

    11

    Thread Lifecycle (cont.)

    The thread scheduler chooses a thread to execute from thethreads in the pool.

    If another thread is chosen by the scheduler to execute before it

    finishes, it goes back to the thread pool to await its turn again.

    start()New Runnable Running

    Schedulersets thethread toexecute

    start()New Runnable Running

    Scheduler setsthe thread to

    execute

    Scheduler chose another

    runnable thread to execute

  • 8/10/2019 M9 - Concurrency

    12/40

    12

    Thread Lifecycle (cont.)

    A thread may also block, wait or sleep while it was runningcausing it to enter a state where it is alive, but not runnable.

    blocking: thread is waiting for a resource or an event.

    waiting: thread is waiting for a signal from another thread.

    sleep: the thread pauses itself for a specified duration.

    start()New Runnable Running

    Scheduler sets

    the thread toexecute

    Scheduler chose anotherrunnable thread to execute

    block/

    wait/sleep Blocking/waiting/sleep event

    occurs

  • 8/10/2019 M9 - Concurrency

    13/40

    13

    Thread Lifecycle (cont.)

    After a thread recovers from blocking, waiting or sleeping, itreturns to a Runnable state and waits in the pool to be executed

    again.

    start()

    New Runnable Running

    Scheduler setsthe thread to

    execute

    Scheduler chose anotherrunnable thread to execute

    block/

    wait/sleep Blocking/waiting/sleep event

    occursThread recoversfrom

    block/wait/sleep

  • 8/10/2019 M9 - Concurrency

    14/40

    14

    Thread Lifecycle (cont.)

    If the thread finishes its execution by exiting its run() method, itis now a dead thread.

    A dead thread cannot be brought back to life.

    Deadstart()

    New Runnable Running

    Scheduler setsthe thread to

    execute

    Scheduler chose anotherrunnable thread to execute

    block/

    wait/sleep Blocking/waiting/sleep event

    occursThread recovers

    fromblock/wait/sleep

    run() method

    finishes

  • 8/10/2019 M9 - Concurrency

    15/40

    15

    Managing Threads

    Basic Concepts Setting Thread Priority

    Pausing Threads

    Yielding a Thread

    Joining a Thread Synchronizing Threads

  • 8/10/2019 M9 - Concurrency

    16/40

    16

    Basic Concepts

    The application often has very little control in determining thebehavior of threads.

    The application can influence the behavior of threads, but it

    cannot have direct control.

    A variety of factors are taken in by the thread scheduler in

    determining which threads to execute, such as:

    Availability of a CPU resources

    Activity or inactivity of the thread

    Designated priority

  • 8/10/2019 M9 - Concurrency

    17/40

    17

    Basic Concepts (cont.)

    Application logic should never be designed to rely on predictingthread behavior.

    After a thread is caused to block, wait or sleep, it returns to the

    runnable state not the running state, making it impossible to

    determine exactly when it will run again.

  • 8/10/2019 M9 - Concurrency

    18/40

    18

    Thread Priority

    Normally a thread with higher priority will be scheduled to runbefore a thread with a lower priority, but this is not always the

    case.

    The scheduler may choose to run a lower priority thread for

    efficiency reasons or if the thread itself causes the scheduler to

    choose another thread. Implementation of thread priority varies depending on the

    underlying platform, and thus should never be considered as a

    factor when designing application logic.

  • 8/10/2019 M9 - Concurrency

    19/40

    19

    Setting Thread Priority

    A Java thread inherits its default priority from the thread thatcreated it.

    A thread can set its priority by calling its setPriority(int) method.

    Valid values are defined as integers ranging between

    Thread.MIN_PRIORITY and Thread.MAX_PRIORITY.

  • 8/10/2019 M9 - Concurrency

    20/40

    20

    Pausing a Thread

    Calling Thread.sleep(duration) stops the current thread fromexecuting and places it in a state that prevents it from being

    chosen by the scheduler.

    Putting a thread to sleep guarantees that it will not run and will

    not be eligible run for the specified duration.

    When a thread wakes up after being put to sleep, it will beplaced in a Runnable state, and NOT the Running state.

  • 8/10/2019 M9 - Concurrency

    21/40

    21

    Example: Pausing a Thread

    In the initial example, the Worker thread is made to pauseregularly during every iteration of the loop.

    public void work(int taskCount){

    for(int task = 0; task < taskCount ; task++){

    System.out.println("Worker " + name + " doing task " + task);

    try{

    Thread.sleep(delay);

    }

    catch(InterruptedException ex){

    System.err.println("Unexpected interruption of thread " +Thread.currentThread().getName());

    }

    }

    }

    Pausing a running thread allows other threads a chance toexecute.

  • 8/10/2019 M9 - Concurrency

    22/40

    22

    Yielding a Thread

    The Thread.yield() method is intended to cause the currentthread to go back to a runnable state, ideally allowing the

    scheduler to choose another thread to execute.

    Yielding a thread does NOT guarantee that another thread will

    be chosen to run; there is still a chance that the thread that

    yielded will be chosen again.

  • 8/10/2019 M9 - Concurrency

    23/40

    23

    Joining a Thread

    A thread can be told to join a thread at the end by calling thejoin() method of another live thread object.

    This guarantees that the current thread will enter a blocked state

    while the thread object it joined finishes.

    After the joined thread finishes execution, the current thread

    returns to a runnable state.

  • 8/10/2019 M9 - Concurrency

    24/40

    24

    Joining a Thread (cont.)

    Application

    Starts

    Application

    Ends

    Application Life Time

    Main Thread

    Starts

    Larry

    StartsLoop Starts

    i == 3

    Thread blocks

    LarryEnds

    Thread

    resumes Main Thread

    The main thread will block until it joins the Larry thread when the

    Larry thread finishes.

    ** Refer to the JoinThreadSample.java sample code

  • 8/10/2019 M9 - Concurrency

    25/40

    25

    Thread Interference

    Threads communicate and pass data to each other byaccessing the fields of objects that they share.

    Because of this shared nature it is possible for threads to

    interfere with each other with regards to the objects that they

    share.

    Thread interfering with one another with regards to sharedobjects can result in inconsistent views on the data that they

    share.

    ** Refer to the Incrementer.java, IncrementerSample.java, andThreadIncrementer.java sample code

  • 8/10/2019 M9 - Concurrency

    26/40

    26

    Synchronization and Locks

    Synchronization is one of the tools to avoid thread interference andmemory consistency errors.

    Sections of code can be synchronized so that only one thread at a

    time can execute that section of code.

    Synchronization relies on the concept of a lock that a Thread has

    to acquire before being allowed to execute a section of code.

    When a thread invokes a synchronized method, it automatically

    acquires the Intrinsic Lock for that methods object and releases it

    when the method returns.

    Intrinsic Locks can only be owned by one thread at a time.

  • 8/10/2019 M9 - Concurrency

    27/40

    27

    Synchronized Methods

    A synchronized method guards an entire method from multiplethread access.

    public synchronized void increment(){

    if(x == 10)

    return false;

    x ++;return true;

    }

    Synchronized instance methods relies on a lock associated to

    the current instance.

    Synchronized static methods relies on a class lock.

    ** Refer to the Incrementer.java, IncrementerSample.java, and

    ThreadIncrementer.java sample code

  • 8/10/2019 M9 - Concurrency

    28/40

    28

    Synchronized Blocks

    Greater granularity can be achieved by synchronizing onlycritical blocks inside a method.

    This allows only certain sections of code inside a method to beguarded, and also allows more flexibility in specifying what lockto acquire.

    public void increment(){

    System.out.println(I am not a critical section of code);

    synchronized(this){ //Can also specify another object instance if required

    if(x == 10)

    return false;

    x ++;

    }

    return true;

    }

  • 8/10/2019 M9 - Concurrency

    29/40

    29

    To address the limitations of Intrinsic Locks, Explicit locks in Java5 can be implemented to provide more flexibility.

    Features of Explicit Locks:

    Ability to interrupt a thread waiting for a specific lock.

    A thread can give a timeout value for attempting to acquire the lock;

    Read/write locks are supportedmultiple threads can hold a locksimultaneously for read only access.

    The traditional wait/notify metaphor is extended to allow conditions.

    Support for fairness by following the first-in-first-out order if more thanone thread is waiting for a lock.

    The ability to lock beyond the scope of a block: for example, onemethod can pass a lock object to another thread;

    Ability to query the status and properties of a specific lockprogrammatically (i.e., number of threads waiting to acquire the lock).

    Explicit Locks

  • 8/10/2019 M9 - Concurrency

    30/40

    30

    Coordinating Threads

    Threads will often need to coordinate with one another toaccomplish their tasks.

    One of the more common coordination scenarios is a thread that

    needs to finish a section of code before another thread can

    proceed.

    One way to accomplish this coordination is by making thedependent thread wait until it has been notified by the other

    thread that it can proceed.

  • 8/10/2019 M9 - Concurrency

    31/40

    31

    Coordinating Threads (cont.)

    Objects have a wait/notify mechanism that allows threads tocoordinate with each other.

    The wait() method of an object tells the current thread acting on

    the object to block.

    The thread waiting on the object will continue once the objects

    notify() method has been executed by another thread.

    The wait() and notify() methods of an object can only be

    executed by a thread that has exclusive lock on the object.

    ** Refer to the AnnoyingPassenger.java, AnnoyedDriver.java, andPollingSample.java sample code

  • 8/10/2019 M9 - Concurrency

    32/40

    Creating and Executing Threads

    In J2SE 5.0, the preferred means of creating a multithreaded

    application is to implement the Runnableinterface (package java.lang)

    and use built-in methods and classes to create Threads that execute

    the Runnables.

    The Runnable interface declares a single method named run.

    Runnables are executed by an object of a class that implements the

    Executorinterface (package java.util.concurrent).

    This interface declares a single method named execute.

    An Executor object typically creates and manages a group of threads

    called a thread pool. These threads execute the Runnable objects

    passed to the execute method.

  • 8/10/2019 M9 - Concurrency

    33/40

    Creating and Executing Threads (cont)

    The Executor assigns each Runnable to one of the availablethreads in the thread pool. If there are no available threads inthe thread pool, the Executor creates a new thread or waits for athread to become available and assigns that thread theRunnable that was passed to method execute.

    Depending on the Executor type, there may be a limit to thenumber of threads that can be created.

    Interface ExecutorService(package java.util.concurrent) is a

    subinterface of Executor that declares a number of othermethods for managing the life cycle of the Executor.

    An object that implements the ExecutorService interface can becreated using static methods declared in class Executors

    (package java.util.concurrent).

  • 8/10/2019 M9 - Concurrency

    34/40

    Example

  • 8/10/2019 M9 - Concurrency

    35/40

    Example (Cont)

  • 8/10/2019 M9 - Concurrency

    36/40

  • 8/10/2019 M9 - Concurrency

    37/40

    Example (Cont

  • 8/10/2019 M9 - Concurrency

    38/40

  • 8/10/2019 M9 - Concurrency

    39/40

    39

    Questions and Comments

  • 8/10/2019 M9 - Concurrency

    40/40

    Activity

    1) Open your SEF workspace in

    Eclipse.

    2) In the package explorer, navigate to

    the following package

    sef.module10.activity.

    3) The files TaskQueue and

    QueueWorker attempt to simulate a

    very common pattern when taking

    advantage of Threads. Take the

    time to review the implementation

    and attempt to describe the pattern

    and review its benefits.