slides - lab chapter 5 - java threads

Upload: isaiah-james-vacalares

Post on 05-Apr-2018

224 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    1/128

    Operating

    Systems1

    Lab 05 Java Threads

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    2/128

    Operating

    Systems2

    Outline

    Creating a Java Thread

    Synchronized Keyword

    Wait and Notify

    High Level Cuncurrency Objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    3/128

    Operating

    Systems3

    Creating a Java thread

    Java threads are a way to have different parts of yourprogram running at the same time.

    For example, you can create an application that accepts

    input from different users at the same time, each userhandled by a thread.

    Also, most networking applications involve threads

    you would need to create a thread that would wait for incomingmessages while the rest of your program handles your outgoing

    messages.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    4/128

    Operating

    Systems4

    Creating a Java thread

    There are two ways to create a java thread

    Extending the Thread class

    Implementing the runnable interface

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    5/128

    Operating

    Systems5

    Basic threads

    We will create a thread that simply prints out a number 500times in a row.

    class MyThread extends Thread {

    int i;MyThread(int i) {this.i = i;

    }public void run() {

    for (int ctr=0; ctr < 500; ctr++) {System.out.print(i);

    }}

    }

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    6/128

    Operating

    Systems6

    Basic threads

    To show the difference between parallel and non-parallelexecution, we have the following executableMyThreadDemo class

    class MyThreadDemo {public static void main(String args[]) {

    MyThread t1 = new MyThread(1);MyThread t2 = new MyThread(2);MyThread t3 = new MyThread(3);t1.run();t2.run();

    t3.run();System.out.print("Main ends");

    }}

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    7/128

    Operating

    Systems7

    Basic threads

    Upon executing MyThreadDemo, we get output that lookslike this

    $ java MyThreadDemo

    1111111111...22222222.....33333......Main ends

    As can be seen, our program first executed t1's run method,which prints 500 consecutive 1's.

    After that t2's run method, which prints consecutuve 2's, andso on.

    Main ends appears at the last part of the output as it is thelast part of the program.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    8/128

    Operating

    Systems8

    Basic threads

    What happened was serial execution, no multithreadedexecution occurred

    This is because we simply called MyThread's run() method

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    9/128

    Operating

    Systems9

    Basic threads

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    10/128

    Operating

    Systems10

    Basic threads

    To start parallel execution, we call MyThread's start()method, which is built-in in all thread objects.

    class MyThreadDemo {

    public static void main(String args[]) {MyThread t1 = new MyThread(1);MyThread t2 = new MyThread(2);MyThread t3 = new MyThread(3);t1.start();t2.start();t3.start();

    System.out.print("Main ends");}}

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    11/128

    OperatingSystems

    11

    Basic threads

    When we run MyThreadDemo we can definitely see thatthree run methods are executing at the same time

    > java MyThreadDemo

    111111111122331122321122333331111Main ends111333222...

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    12/128

    OperatingSystems

    12

    Basic threads

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    13/128

    OperatingSystems

    13

    Basic threads

    Note the appearance of the "Main ends" string in the middleof the output sequence

    > java MyThreadDemo

    111111111122331122321122333331111Main ends111333222...

    This indicates that the main method has already finishedexecuting while thread 1, thread 2 and thread 3 are stillrunning.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    14/128

    OperatingSystems

    14

    Basic threads

    Running a main method creates a thread.

    Normally, your program ends when the main thread ends.

    However, creating and then running a thread's start method

    creates a whole new thread that executes its run() methodindependent of the main method.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    15/128

    OperatingSystems

    15

    Implementing runnable

    Another way to create a thread is to implement theRunnable interface.

    This may be desired if you want your thread to extendanother class.

    By extending another class, you will be unable to extend classthread as Java classes can only extend a single class.

    However, a class can implement more than one interface.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    16/128

    OperatingSystems

    16

    Implementing runnable

    The following is our MyThread class created byimplementing the runnable interface.

    class MyThread implements Runnable {

    ... }

    Classes that implement Runnable are instantiated in adifferent way.

    Thread t1 = new Thread(new MyThread(1));

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    17/128

    OperatingSystems

    17

    Implementing runnable

    Note that implementing an interface requires you to defineall the methods in the interface

    For the Runnable interface, you are required in yourimplementing class to define the run() method or yourprogram will not run.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    18/128

    OperatingSystems

    18

    Pausing threads

    Threads can be paused by the sleep() method.

    For example, to have MyThread pause for half a secondbefore it prints the next number, we add the following linesof code to our for loop.

    for (int ctr=0; ctr < 500; ctr++) {System.out.print(i);try {

    Thread.sleep(500); // 500 miliseconds} catch (InterruptedException e) { }

    }

    Thread.sleep() is a static method of class thread and can beinvoked from any thread, including the main thread.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    19/128

    OperatingSystems

    19

    Pausing threadsfor (int ctr=0; ctr < 500; ctr++) {

    System.out.print(i);try {

    Thread.sleep(500); // 500 miliseconds} catch (InterruptedException e) { }

    }

    The InterruptedException is an unchecked exeception that isthrown by code that stops a thread from running.

    Unchecked exception causing lines must be enclosed in a try-catch,in this case, Thread.sleep().

    An InterruptedException is thrown when a thread is waiting,sleeping, or otherwise paused for a long time and anotherthread interrupts it using the interrupt() method in classThread.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    20/128

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    21/128

    OperatingSystems

    21

    Outline

    Creating a Java Thread

    Synchronized Keyword

    Wait and Notify

    High Level Cuncurrency Objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    22/128

    OperatingSystems

    22

    The Critical Section Problem

    This section we will find out how to implement a solution tothe critical section problem using Java

    Recall that only a single process can enter its criticalsection, all other processes would have to wait

    No context switching occurs inside a critical section

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    23/128

    OperatingSystems

    23

    The Critical Section Problem

    Instead of printing a continuous stream of numbers,MyThread calls a print10() method in a class MyPrinter

    print10() prints 10 continuous numbers on a single line before anewline.

    Our goal is to have these 10 continuous numbers printedwithout any context switches occuring.

    Our output should be:

    ...1111111111

    1111111111222222222233333333331111111111

    ...

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    24/128

    OperatingSystems

    24

    MyPrinter

    We define a class MyPrinter that will have our print10()method

    class MyPrinter {

    public void print10(int value) {for (int i = 0; i < 10; i++) {

    System.out.print(value);}System.out.println(""); // newline after 10 numbers

    }}

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    25/128

    OperatingSystems

    25

    MyThread (revised)

    Instead of printing numbers directly, we use the print10()method in MyThread, as shown by the following

    class MyThread extends Thread {

    int i;MyPrinter p;MyThread(int i) {

    this.i = i;p = new MyPrinter();

    }public void run() {

    for (int ctr=0; ctr < 500; ctr++) {p.print10(i);

    }}

    }

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    26/128

    OperatingSystems

    26

    MyThreadDemo (revised)

    First, we will try to see the output of just a single threadrunning.

    class MyThreadDemo {

    public static void main(String args[]) {MyThread t1 = new MyThread(1);// MyThread t2 = new MyThread(2);// MyThread t3 = new MyThread(3);t1.start();// t2.start();// t3.start();

    System.out.print("Main ends");}}

    We comment out

    the other threadsfor now...

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    27/128

    OperatingSystems

    27

    MyThreadDemo

    When we run our MyThreadDemo, we can see that theoutput really does match what we want.

    > java MyThreadDemo1111111111

    1111111111111111111111111111111111111111

    ...

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    28/128

    OperatingSystems

    28

    MyThreadDemo (revised 2)

    However, let us try to see the output with other threads.

    class MyThreadDemo {

    public static void main(String args[]) {MyThread t1 = new MyThread(1);MyThread t2 = new MyThread(2);MyThread t3 = new MyThread(3);t1.start();t2.start();t3.start();

    System.out.print("Main ends");}}

    We run all three

    threads

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    29/128

    OperatingSystems

    29

    MyThreadDemo

    Our output would look like the following

    > java MyThreadDemo11111111111111122222221111

    22233333332...

    We do not achieve our goal of printing 10 consecutivenumbers in a row

    all three threads are executing the print10's method at the same

    time, thus having more than one number appearing on a single line.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    30/128

    OperatingSystems

    30

    Critical Section Problem

    To achieve our goal there should not be any contextswitches happening inside print10()

    Only a single thread should be allowed to execute inside print10()

    As can be seen, this is an example of the critical sectionproblem

    To solve this, we can use some of the techniques discussedin our synchronization chapter

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    31/128

    OperatingSystems

    31

    Synchronized keyword

    Now we will discuss Java'ssolution to the criticalsection problem

    Java uses a monitor

    construct Only a single thread may run

    inside the monitor

    Even if P2 is calling method2(), ithas to wait for P1 to finish

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    32/128

    OperatingSystems

    32

    Synchronized keyword

    To turn an object into a monitor, simply put the synchronizedkeyword on your method definitions

    Only a single thread can run any synchronized method in an object

    class MyPrinter {public synchronized void print10(int value) {

    for (int i = 0; i < 10; i++) {System.out.print(value);

    }System.out.println(""); // newline after 10 numbers

    }}

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    33/128

    OperatingSystems

    33

    Still not working!

    However, even if we did turn our print10() method into asynchronized method, it will still not work

    > java MyThreadDemo1111111111

    111112222222111122233333332...

    To find out how to make it work, we need to first find outhow the synchronized keyword works

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    34/128

    OperatingSystems

    34

    Intrinsic locks

    Every object in Java has an intrinsic lock

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    35/128

    OperatingSystems

    35

    Intrinsic locks

    When a thread tries to run a synchronized method, it firsttries to get a lock on the object

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    36/128

    OperatingSystems

    36

    Intrinsic locks

    If a thread is successful, then it owns the lock and executesthe synchronized code.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    37/128

    OperatingSystems

    37

    Intrinsic locks

    Other threads cannot run the synchronized code becausethe lock is unavailable

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    38/128

    OperatingSystems

    38

    Intrinsic locks

    Threads can only enter once the thread owning the lockleaves the synchronized method

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    39/128

    OperatingSystems 39

    Intrinsic Locks

    Waiting threads would then compete on who gets to go next

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    40/128

    OperatingSystems 40

    MyThreadDemo Failure

    So why doesn't our example work?

    Because each thread has its own copy of the MyPrinterobject!class MyThread extends Thread {

    int i;MyPrinter p;MyThread(int i) {

    this.i = i;p = new MyPrinter(); // each MyThread creates its own MyPrinter!

    }public void run() {

    for (int ctr=0; ctr < 500; ctr++) {p.print10(i);

    }}

    }

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    41/128

    OperatingSystems 41

    Different Locks

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    42/128

    OperatingSystems 42

    Important

    Recall our definition of synchronized methods

    Only a single thread can run any synchronized method in an object

    Since each thread has its own MyPrinter object, then nolocking occurs

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    43/128

    OperatingSystems43

    Solution

    So, to make it work, all threads must point to the sameMyPrinter object

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    44/128

    OperatingSystems44

    Solution

    Note how all MyThreads now have the same MyPrinterobject

    class MyThread extends Thread {int i;MyPrinter p;MyThread(int i, MyPrinter p) {

    this.i = i; this.p = p}public synchronized void run() {

    for (int ctr=0; ctr < 500; ctr++) {p.print10(i);

    }}

    }

    class MyThreadDemo {public static void main(String args[]) {

    MyPrinter p = new MyPrinter();MyThread2 t1 = new MyThread2(1,p);

    MyThread2 t2 = new MyThread2(2,p);MyThread2 t3 = new MyThread2(3,p);t1.start();t2.start();t3.start();

    }}

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    45/128

    OperatingSystems45

    Solution

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    46/128

    OperatingSystems46

    Locks and Doors

    A way to visualize it is that all Java objects can be doors

    A thread tries to see if the door is open

    Once the thread goes through the door, it locks it behind it,

    No other threads can enter the door because our first thread haslocked it from the inside

    Other threads can enter if the thread inside unlocks the door andgoes out

    Lining up will only occur if everyone only has a single door to thecritical region

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    47/128

    OperatingSystems47

    Synchronized methods

    Running MyThreadDemo now correctly shows synchronizedmethods at work

    >java MyThreadDemo11111111111111111111111111111122222222223333333333...

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    48/128

    Operating

    Systems48

    Remember

    Only a single thread can run any synchronized method in anobject

    If an object has a synchronized method and a regular method, onlyone thread can run the synchronized method while multiple threadscan run the regular method

    Threads that you want to have synchronized must share thesame monitor object

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    49/128

    Operating

    Systems49

    Synchronized blocks

    Aside from synchronized methods, Java also allows forsynchronized blocks.

    You must specify what object the intrinsic lock comes from

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    50/128

    Operating

    Systems50

    Synchronized blocks

    Our print10() implementation, done using synchronizedstatements, would look like this

    class MyPrinter {

    public void print10(int value) {synchronized(this) {for (int i = 0; i < 10; i++) {

    System.out.print(value);}System.out.println(""); // newline after 10 numbers

    }}}

    We use a MyPrinter object for thelock, replicating what the

    synchronized method does

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    51/128

    Operating

    Systems51

    Synchronized blocks

    Synchronized blocks allow for flexibility, in the case if wewant our intrinsic lock to come from an object other than thecurrent object.

    For example, we could define MyThread's run method to

    perform the lock on the MyPrinter object before callingprint10

    class MyThread extends Thread {MyPrinter p;...public void run() {

    for (int i = 0; i < 100; i++) {

    synchronized(p) {p.print10(value);

    }}}}

    Note that any linesbefore and after oursynchronized block can

    be executedconcurrently by threads

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    52/128

    Operating

    Systems52

    Multiple locks

    Also, the use of the synchronized block allows for moreflexibility by allowing different parts of code to be locked withdifferent objects.

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    53/128

    Operating

    Systems53

    Multiple locks

    For example, consider a modified MyPrinter which has twomethods, which we'll allow to run concurrentlyclass MyPrinter {

    Object lock1 = new Object();Object lock2 = new Object();public void print10(int value) {

    synchronized(lock1) {for (int i = 0; i < 10; i++) {

    System.out.print(value);}System.out.println(""); // newline after 10 numbers

    }}

    public int squareMe(int i) {synchronized (lock2) {return i * i;

    }}

    }

    The blocks inside print10()and squareMe() can run atthe same time because theyuse different objects for theirlocking mechanism

    Synchronization still applies.For example only a singlethread can run thesynchronized block insquareMe() at any point intime

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    54/128

    Operating

    Systems54

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    55/128

    Operating

    Systems55

    Outline

    Creating a Java Thread

    Synchronized Keyword

    Wait and Notify

    High Level Cuncurrency Objects

    P d C bl

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    56/128

    Operating

    Systems56

    Producer-Consumer problem

    We will now discuss a solution to the Producer-Consumerproblem.

    Instead of using beer, the producer will store in a sharedstack a random integer value which will be retrieved by the

    consumer process.

    P d C

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    57/128

    Operating

    Systems57

    Producer-Consumer

    P d C C d

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    58/128

    Operating

    Systems58

    Producer-Consumer Code

    P d C

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    59/128

    Operating

    Systems59

    Producer-Consumer

    As can be seen, we would need to have a place to store ourarray of integers and our top variable, which should beshared among our producer and consumer.

    MAXCOUNT is the maximum number of items the Producerproduces

    We'll assume the maximum array size of 10000 for now

    class SharedVars {final int MAXCOUNT = 100;int array[] = new int[10000];

    int top;

    // }

    P d C

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    60/128

    Operating

    Systems60

    Producer-Consumer

    To keep things object-oriented, we will place the code forplacing values in the stack and getting values in the stack inour SharedVars class

    Our next slide shows our implementation

    Sh dV

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    61/128

    Operating

    Systems

    61

    class SharedVars {final int MAXCOUNT = 100;int array[] = new int[10000];int top;

    // method for inserting a valuepublic void insertValue(int value) {

    if (top < array.length) {

    array[top] = value;top++;

    }}// method for getting a valuepublic int getValue() {

    if (top > 0) {top--;

    return array[top];}else

    return -1;}}

    SharedVars

    SharedVars

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    62/128

    Operating

    Systems

    62

    SharedVars

    SharedVars insertValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    63/128

    Operating

    Systems

    63

    SharedVars insertValue()

    SharedVars insertValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    64/128

    Operating

    Systems

    64

    SharedVars insertValue()

    SharedVars insertValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    65/128

    Operating

    Systems

    65

    SharedVars insertValue()

    SharedVars insertValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    66/128

    Operating

    Systems

    66

    SharedVars insertValue()

    SharedVars insertValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    67/128

    Operating

    Systems

    67

    SharedVars insertValue()

    SharedVars getValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    68/128

    Operating

    Systems

    68

    SharedVars getValue()

    SharedVars getValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    69/128

    Operating

    Systems

    69

    SharedVars getValue()

    SharedVars getValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    70/128

    Operating

    Systems

    70

    SharedVars getValue()

    SharedVars getValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    71/128

    Operating

    Systems

    71

    SharedVars getValue()

    SharedVars getValue()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    72/128

    Operating

    Systems

    72

    SharedVars getValue()

    Producer-Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    73/128

    Operating

    Systems

    73

    Producer Consumer

    Now we will slowly build our Producer and Consumer class

    We can say that our Producer and Consumer should beimplemented as threads.

    Thus we have our code below, including a class that starts these

    threadsclass Producer extends Thread {

    public void run() {}

    }

    class Consumer extends Thread {public void run() {}

    }

    class PCDemo {

    public static void main(String args[]) {Producer p = new Producer();Consumer c = new Consumer();p.start();c.start();

    }}

    Producer-Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    74/128

    Operating

    Systems

    74

    Producer Consumer

    Producer and Consumer should have the same SharedVarsobject

    class Producer extends Thread {SharedVars sv;Producer(SharedVars sv) {

    this.sv = sv;}public void run() {}

    }

    class Consumer extends Thread {SharedVars sv;Consumer(SharedVars sv) {

    this.sv = sv;}public void run() {}

    }

    class PCDemo {public static void main(String args[]) {

    SharedVars sv = new SharedVars();Producer p = new Producer(sv);Consumer c = new Consumer(sv);p.start();c.start();

    }}

    Producer-Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    75/128

    Operating

    Systems

    75

    Producer Consumer

    There is no more need to modify our PCDemo class so wewill not show it anymore.

    Producer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    76/128

    Operating

    Systems

    76

    Producer

    We want our producer to produce a random integer andstore it in SharedVars. Thus our Producer code would looklike this

    class Producer extends Thread {SharedVars sv;

    Producer(SharedVars sv) {this.sv = sv;}public void run() {

    int value = (int)(Math.random() * 100); // random value from 0 to 100sv.insertValue(value);System.out.println("Producer: Placing value: " + value);

    }

    }

    Producer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    77/128

    Operating

    Systems

    77

    Producer

    We want our Producer to do this a hundred times, so we willadd a loop to our code

    class Producer extends Thread {SharedVars sv;Producer(SharedVars sv) {

    this.sv = sv;}public void run() {

    for (int i = 0; i < 100; i++) {int value = (int)(Math.random() * 100); // random value from 0 to 100sv.insertValue(value);System.out.println("Producer: Placing value: " + value);

    }

    }}

    Producer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    78/128

    Operating

    Systems

    78

    Producer

    Finally, twe have our producer pause for a maximum of 5seconds each time it places a value

    class Producer extends Thread {SharedVars sv;Producer(SharedVars sv) {

    this.sv = sv;

    }public void run() {

    for (int i = 0; i < 100; i++) {int value = (int)(Math.random() * 100); // random value from 0 to 100sv.insertValue(value);System.out.println("Producer: Placing value: " + value);

    try { Thread.sleep((int)(Math.random() * 5000)); // sleep 5s max} catch (InterruptedException e) { }

    }}

    }

    Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    79/128

    Operating

    Systems

    79

    Co su e

    Now, we want our consumer to get a value from SharedVars

    class Consumer extends Thread {SharedVars sv;Consumer(SharedVars sv) {

    this.sv = sv;}public void run() {

    int value = sv.getValue();System.out.println("Consumer: I got value:" + value);

    }}

    Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    80/128

    Operating

    Systems

    80

    We want to get a value 100 times

    class Consumer extends Thread {SharedVars sv;Consumer(SharedVars sv) {

    this.sv = sv;}public void run() {

    for (int i = 0; i < 100; i++) {int value = sv.getValue();System.out.println("Consumer: I got value:" + value);

    }}

    }

    Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    81/128

    Operating

    Systems

    81

    Finally, just like producer, we pause for a maximum of 5seconds on each loop

    class Consumer extends Thread {SharedVars sv;Consumer(SharedVars sv) {

    this.sv = sv;}public void run() {

    for (int i = 0; i < 100; i++) {int value = sv.getValue();System.out.println("Consumer: I got value:" + value);

    try {

    Thread.sleep((int)(Math.random() * 5000)); // sleep 5s max} catch (InterruptedException e) { }

    }}

    }

    Race Condition

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    82/128

    Operating

    Systems

    82

    As was discussed in a previous chapter, we try to avoid arace condition between insertValue() and getValue()

    Consumer getValue(): top = top 1

    Producer insertValue(): array[top] = value // this would overwrite an existing value!Producer insertValue(): top = top + 1Consumer getValue(): return array[top] // consumer returns an already returned value

    Race Condition

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    83/128

    Operating

    Systems

    83

    Race Condition

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    84/128

    Operating

    Systems

    84

    We do not want getValue() and insertValue() to run at thesame time

    Therefore, we modify SharedVars to use synchronizedblocks

    We could also use synchronized methods but we need some non-synchronized commands

    Synchronized SharedVars

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    85/128

    Operating

    Systems

    85

    class SharedVars {final int MAXCOUNT = 100;

    int array[] = new int[10000];int top;

    public void insertValue(int value) { // method for inserting a valuesynchronized(this) {

    if (top < array.length) {array[top] = value;top++;

    }}

    }public int getValue() { // method for getting a value

    synchronized(this) {if (top > 0) {

    top--;return array[top];

    }else

    return -1;}

    }}

    y

    Synchronized SharedVars

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    86/128

    Operating

    Systems

    86

    Synchronized SharedVars

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    87/128

    Operating

    Systems

    87

    Producer-Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    88/128

    Operating

    Systems

    88

    Upon executing our program, the output of our code wouldlook something like this:

    Producer inserts value: 15Consumer got: 15Consumer got: -1Producer inserts value: 50Producer inserts value: 75

    Consumer got: 75...

    Note that both Consumer and Producer are running at thesame time.

    Got -1?

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    89/128

    Operating

    Systems

    89

    Producer inserts value: 15

    Consumer got: 15Consumer got: -1Producer inserts value: 50Producer inserts value: 75Consumer got: 75...

    Notice that, if we try to get a value from the array and thereisn't any, we return a value -1.

    You can see this clearly if you increase the Producer delay to 10s.

    Producer adds a value every 10s, consumer gets one every 5s

    Wouldn't it be better if we have our Consumer wait for theProducer to produce something instead of just getting -1?

    Busy wait

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    90/128

    Operating

    Systems

    90

    We could implement a busy wait for this

    public int getValue() {while (top

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    91/128

    Operating

    Systems

    91

    A better solution is to use the wait() method, defined in classObject, and is therefore inherited by all objects

    A thread invoking wait() will suspend the thread

    However, a thread invoking wait() must own the intrinsic lock

    of the object it is calling wait() from If we are going to call this.wait() it has to be in synchronized(this)

    block

    Also, as with all methods that suspend thread execution, likejoin() and sleep(), our wait() method must be in a try-catch

    block that catches InterruptedExceptions.

    The wait() method

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    92/128

    Operating

    Systems

    92

    // called by Consumer threadpublic int getValue() {

    synchronized(this) {if (top

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    93/128

    Operating

    Systems

    93

    All threads that call wait() on an object are placed in a poolof waiting threads for that object.

    Execution resumes when another thread calls the notify()method of the object our first thread is waiting on

    The notify() method is defined in class Object. All objects have wait() and notify()

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    94/128

    Operating

    Systems

    94

    For our example, our producer thread, after inserting on anempty array, would notify the consumer thread that it hasplaced a value in our array by calling the notify() method onthe SharedVars object

    Recall that Producer and Consumer both have a reference to the

    same SharedVars object.

    The producer calling notify() from insertValue() would inform any theconsumer waiting on the same SharedVar object.

    The notify() method

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    95/128

    Operating

    Systems

    95

    // called by producerpublic void insertValue(int value) {

    synchronized(this) {if (top < array.length) {

    array[top] = value;

    top++;if (top == 1) { // we just inserted on an empty array

    this.notify(); // notify sleeping thread}

    }}

    }

    class SharedVars {final int MAXCOUNT = 100;int array[] = new int[10000];int top;

    Final SharedVars

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    96/128

    Operating

    Systems96

    int top;

    public void insertValue(int value) {synchronized(this) {

    if (top < array.length) {array[top] = value;top++;if (top == 1) { // we just inserted on an empty array

    this.notify(); // notify any sleeping thread}

    }

    }}

    public int getValue() {synchronized(this) {

    if (top

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    97/128

    Operating

    Systems97

    When the notify() method of an object is called, then a singlewaiting thread on that object is signaled to get ready toresume execution.

    After our Producer thread exists insertValue and releasesthe lock, our Consumer thread gets the lock once again andresumes its execution.

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    98/128

    Operating

    Systems98

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    99/128

    Operating

    Systems99

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    100/128

    Operating

    Systems100

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    101/128

    Operating

    Systems101

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    102/128

    Operating

    Systems102

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    103/128

    Operating

    Systems103

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    104/128

    Operating

    Systems104

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    105/128

    Operating

    Systems105

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    106/128

    Operating

    Systems106

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    107/128

    Operating

    Systems107

    Another method called notifyAll() notifies all the waitingthreads.

    These waiting threads would then compete to see whichsingle thread resumes execution, the rest of the threadswould once again wait.

    Producer-Consumer

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    108/128

    Operating

    Systems108

    If you run the demo program again, you can see that, even ifthe producer is slow, the consumer waits until the producergives out a value before getting that value

    Note that you must also consider inserting on a full array

    Producer must wait until consumer has taken away some valuesbefore inserting

    We will leave the implementation of this as an exercise

    Wait() and notify()

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    109/128

    Operating

    Systems109

    Note that this same thing must occur on inserting on a fullarray

    Producer must wait until consumer has taken away some valuesbefore inserting

    We will leave the implementation of this as an exercise.

    Outline

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    110/128

    Operating

    Systems110

    Creating a Java Thread Synchronized Keyword

    Wait and Notify

    High Level Cuncurrency Objects

    High level concurrency objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    111/128

    Operating

    Systems111

    Since Java 1.5, additional classes have been added in thejava.util.concurrent package that assist in the creation andmanipulation of threads.

    These high-level concurrency objects are

    Lock objects

    Executors

    Concurrent Collections

    Atomic Variables

    Lock objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    112/128

    Operating

    Systems112

    Any object in Java can be used as a lock forsynchronization. However, the java.util.concurrent.lockspackage defines classes that have additional lockingfeatures.

    The basic interface of this package is the Lock interface.

    Lock objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    113/128

    Operating

    Systems113

    An object of type Lock can only be owned by a single threadat a time.

    To aquire a lock, a thread must call its lock() method.

    To release a lock, it must call its unlock() method.

    In summary, instead of the implicit locking and unlocking ofa synchronized block or method, a lock provides theflexibility of manually calling lock() and unlock() methods.

    Lock objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    114/128

    Operating

    Systems114

    A Lock also has a tryLock() method. This tryLock() method returns a true or false value,

    true if it managed to get the lock, false otherwise.

    The program does not block if tryLock() does not succeed,

    in contrast to the lock() method, This is the behavior of a thread if it tries to enter a sychronized block

    or method.

    In addition, a different version of tryLock() allows you tospecify the amount of time the thread waits to establish a

    lock before it returns true or false.

    Lock objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    115/128

    Operating

    Systems115

    The folowing is an implementation of MyPrinter with Locksimport java.util.concurrent.locks.*;class MyPrinter {

    final Lock l = new ReentrantLock(); // ReentrantLock is an implementation// of the Lock interface

    public void print10(int value) {boolean gotLock = false;while(!gotLock) {

    gotLock = l.tryLock();if (!gotLock) {

    System.out.println("Unable to get lock, try again next time");try {

    Thread.sleep((int)(Math.random() * 1000)); // wait until try again} catch (InterruptedException e) { }

    }}for (int i = 0; i < 10; i++) {

    System.out.print(value);}System.out.println(""); // newline after 10 numbersl.unlock();

    }}

    Lock objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    116/128

    Operating

    Systems116

    Wait() and notify() can be called from lock objects using aConditions object

    A Conditon object can be extracted from a lock using itsnewCondition() method

    Conditions have an await() method which simulates wait()

    A signal() method is the equivalent of notify() which notify'sobjects awaiting on that lock.

    Lock objects

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    117/128

    Operating

    Systems117

    The following slide shows our SharedVars class that usesLocks and Conditions

    import java.util.concurrent.lock.*;class SharedVars {

    final Lock mylock = new ReentrantLock();final Condition notEmpty = mylock.getCondition();final int MAXCOUNT = 100;int array[] = new int[10000];

    Advanced SharedVars

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    118/128

    Operating

    Systems118

    int top;

    public void insertValue(int value) {mylock.lock();

    if (top < array.length) {array[top] = value;top++;if (top == 1) { // we just inserted on an empty array

    notEmpty.signal(); // notify any sleeping thread

    }}

    mylock.unlock();}public int getValue() {

    mylock.lock();if (top

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    119/128

    Operating

    Systems119

    Whenever we create a thread, we manually state when thatthread is executed. For instance, given the following thread:

    class MyThread implements Runnable { ... }

    We manually start the thread by the two commands:

    Thread t1 = new Thread(mt1);

    t1.start();

    Executors

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    120/128

    Operating

    Systems120

    An implementing class of the Executor interface abstractsthread starting from the programmer.

    For instance, instead of the above code, we have thefollowing:

    MyThread mt1 = new MyThread();

    Executor e = new ThreadPoolExecutor(10);

    e.execute(mt1);

    e.execute(otherThreads);

    Executors

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    121/128

    Operating

    Systems121

    Our example uses the ThreadPoolExecutor class. This class runs our inputted threads (via the execute()

    method) via a ready pool of execution threads (in this case,10 working threads).

    These execution threads reduce the overhead needed forthread creation

    a thread is mearly passed as a parameter to an already runningworker thread for execution.

    Executors

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    122/128

    Operating

    Systems122

    The ScheduledThreadPoolExecutor class, has methods thatallow for a partciular thread to start at a certain time of theday, or be repeated periodically.

    Concurrent Collections

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    123/128

    Operating

    Systems123

    The java.util.concurrent package includes collection classesthat can be used with multithreaded programs use withouthaving to worry about synchronization problems.

    For instance, the BlockingQueue class creates a first-in-firstout queue that automatically blocks threads when they try to

    add to a full queue or retreve values from an empty one. Execution automatically resumes when another thread

    removes a value from a full queue or adds data to an emptyone.

    Atomic Variables

    A h i P d C bl th

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    124/128

    Operating

    Systems124

    As we have seen in our Producer-Consumer problem, thefollowing commands must be executed without anyinterleaving. :

    array[top] = ;

    top++;

    This is called atomic execution, where each command mustbe executed as a single whole.

    Atomic Variables

    H i l d t t i C id

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    125/128

    Operating

    Systems125

    However, even single commands are not atomic. Considerthe command top++

    Top++ is divided into three parts when run on the CPU

    1. Get the value of top

    2. Add 1 to that value

    3. Save that value to the address of top.

    Atomic Variables

    All th th d t b t d ith t

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    126/128

    Operating

    Systems126

    All these three commands must be executed without anyinterleaving commands from other threads.

    One way around this is to have a synchronized incrementmethod.

    class SharedVars {

    int top;

    public synchronized inctop() {

    top++;

    }

    }

    Atomic Variables

    Most of the other arithmetic operations are sadl non

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    127/128

    Operating

    Systems127

    Most of the other arithmetic operations are sadly, non-atomic as well

    This means that, when dealing with shared variables, anymanipulation must be in a synchronized block

    This includes even assignment statements.

    To avoid this tediousness, the java.util.concurrent.atomicpackage provides already thread-safe classes.

    Atomic Variables

    For instance the AtomicInteger class provides some of the

  • 7/31/2019 Slides - Lab Chapter 5 - Java Threads

    128/128

    Operating

    Systems128

    For instance, the AtomicInteger class provides some of themethods below:

    void incrementAndGet() - performs an increment operationatomically

    void addAndGet(int delta) adds delta to the AtomicInteger

    atomically. There are also implemetnations like this for an integer array

    or an object reference variable.