CmpSci 187: Programming with Data Structures Spring 2015

Similar documents
CMPSCI 187: Programming With Data Structures. Lecture #20: Concurrency and a Case Study David Mix Barrington 24 October 2012

CmpSci 187: Programming with Data Structures Spring 2015

CS61B, Spring 2003 Discussion #17 Amir Kamil UC Berkeley 5/12/03

Computation Abstractions. Processes vs. Threads. So, What Is a Thread? CMSC 433 Programming Language Technologies and Paradigms Spring 2007

CS 351 Design of Large Programs Threads and Concurrency

Concurrent Programming using Threads

CMPSCI 187: Programming With Data Structures. Lecture 12: Implementing Stacks With Linked Lists 5 October 2011

THREADS AND CONCURRENCY

CPS221 Lecture: Threads

CmpSci 187: Programming with Data Structures Spring 2015

Exercise Session Week 8

Computer Science 62. Bruce/Mawhorter Fall 16. Midterm Examination. October 5, Question Points Score TOTAL 52 SOLUTIONS. Your name (Please print)

Exercise Session Week 8

Java Threads and intrinsic locks

B2.52-R3: INTRODUCTION TO OBJECT ORIENTATED PROGRAMMING THROUGH JAVA

Note: Each loop has 5 iterations in the ThreeLoopTest program.

Performance Throughput Utilization of system resources

Threads and Parallelism in Java

CSE332: Data Abstractions Lecture 22: Shared-Memory Concurrency and Mutual Exclusion. Tyler Robison Summer 2010

public static boolean isoutside(int min, int max, int value)

G51PGP Programming Paradigms. Lecture 009 Concurrency, exceptions

EECS2030 Week 7 worksheet Tue Feb 28, 2017

Ch. 11: References & the Copy-Constructor. - continued -

Overview. CMSC 330: Organization of Programming Languages. Concurrency. Multiprocessors. Processes vs. Threads. Computation Abstractions

CMPSCI 187: Programming With Data Structures. Lecture #21: Array-Based Lists David Mix Barrington 26 October 2012

Java Threads. COMP 585 Noteset #2 1

CSIS 10B Lab 2 Bags and Stacks

1.00 Lecture 29. Sensors and Threads. Reading for next time: Numerical Recipes (online)

CmpSci 187: Programming with Data Structures Spring 2015

Multiple Inheritance. Computer object can be viewed as

Synchronization SPL/2010 SPL/20 1

09/02/2013 TYPE CHECKING AND CASTING. Lecture 5 CS2110 Spring 2013

CMPSCI 187: Programming With Data Structures. Lecture #11: Implementing Stacks With Arrays David Mix Barrington 28 September 2012

Written by John Bell for CS 342, Spring 2018

CS 326: Operating Systems. Process Execution. Lecture 5

Chair of Software Engineering. Java and C# in Depth. Prof. Dr. Bertrand Meyer. Exercise Session 8. Nadia Polikarpova

G52CON: Concepts of Concurrency

CMPSCI 187 / Spring 2015 Postfix Expression Evaluator

COMP 213. Advanced Object-oriented Programming. Lecture 23. Shared Variables and Synchronization

Appendix: Common Errors

UMBC CMSC 331 Final Exam

Exceptions. What exceptional things might our programs run in to?

Lecture 35. Threads. Reading for next time: Big Java What is a Thread?

Synchronized Methods of Old Versions of Java

Java s Implementation of Concurrency, and how to use it in our applications.

CSE 332: Data Structures & Parallelism Lecture 17: Shared-Memory Concurrency & Mutual Exclusion. Ruth Anderson Winter 2019

Lecture 8: September 30

CS/ENGRD 2110 SPRING Lecture 2: Objects and classes in Java

Only one thread can own a specific monitor

Lecture 11 Unbounded Arrays

CSC 1052 Algorithms & Data Structures II: Linked Queues

CMSC Introduction to Algorithms Spring 2012 Lecture 7

CS180 Spring 2010 Exam 2 Solutions, 29 March, 2010 Prof. Chris Clifton

Introduction to Computing II (ITI 1121) Final Examination

CMPSCI 187: Programming With Data Structures. Lecture #16: Thinking About Recursion David Mix Barrington 12 October 2012

CS/B.TECH/CSE(New)/SEM-5/CS-504D/ OBJECT ORIENTED PROGRAMMING. Time Allotted : 3 Hours Full Marks : 70 GROUP A. (Multiple Choice Type Question)

Lecture 9: Introduction to Monitors

Programming Language Concepts: Lecture 11

ITI Introduction to Computing II

Soda Machine Laboratory

class objects instances Fields Constructors Methods static

CSE 331 Midterm Exam 2/13/12

3. Convert 2E from hexadecimal to decimal. 4. Convert from binary to hexadecimal

Writing your own Exceptions. How to extend Exception

Process Scheduling. Copyright : University of Illinois CS 241 Staff

CMSC 330: Organization of Programming Languages. Threads Classic Concurrency Problems

cs Java: lecture #6

CSE 331 Midterm Exam Sample Solution 2/13/12

Models of concurrency & synchronization algorithms

CMSC 433 Section 0101 Fall 2012 Midterm Exam #1

Multitasking Multitasking allows several activities to occur concurrently on the computer. A distinction is usually made between: Process-based multit

Michele Van Dyne MUS 204B Concurrency Issues

Summary Semaphores. Passing the Baton any await statement. Synchronisation code not linked to the data

The Dining Philosophers Problem CMSC 330: Organization of Programming Languages

A Third Look At Java. Chapter Seventeen Modern Programming Languages, 2nd ed. 1

CMPSCI 187 / Spring 2015 Implementing Sets Using Linked Lists

CMPSCI 187: Programming With Data Structures. Lecture #23: Linked Lists David Mix Barrington 31 October 2012

16. Linked Structures and Miscellaneous

CS113: Lecture 7. Topics: The C Preprocessor. I/O, Streams, Files

CMPS 240 Data Structures and Algorithms Test #2 Fall 2017 November 15

Problems with Concurrency. February 19, 2014

CMPSCI 377 Midterm (Sample) Name:

ENCM 501 Winter 2019 Assignment 9

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

CMPSCI 187 / Spring 2015 Hangman

CMSC 330: Organization of Programming Languages. The Dining Philosophers Problem

CS211 Computers and Programming Matthew Harris and Alexa Sharp July 9, Boggle

CS125 : Introduction to Computer Science. Lecture Notes #38 and #39 Quicksort. c 2005, 2003, 2002, 2000 Jason Zych

Class 15. Object-Oriented Development from Structs to Classes. Laura Marik Spring 2012 C++ Course Notes (Provided by Jason Minski)

Checked and Unchecked Exceptions in Java

JAVA BASICS II. Example: FIFO

Multithreaded Programming Part II. CSE 219 Stony Brook University, Department of Computer Science

Thinking Functionally

University of Illinois at Urbana-Champaign Department of Computer Science. First Examination

Rules and syntax for inheritance. The boring stuff

Concurrency. CSCI 136: Fundamentals of Computer Science II Keith Vertanen

Shared Objects & Mutual Exclusion

Operating Systems (234123) Spring (Homework 3 Wet) Homework 3 Wet

Overview. Processes vs. Threads. Computation Abstractions. CMSC 433, Fall Michael Hicks 1

Midterm 2. 7] Explain in your own words the concept of a handle class and how it s implemented in C++: What s wrong with this answer?

Transcription:

CmpSci 187: Programming with Data Structures Spring 2015 Lecture #13, Concurrency, Interference, and Synchronization John Ridgway March 12, 2015 Concurrency and Threads Computers are capable of doing more than one thing at the same time. Some computer hardware can actually have two processes going on simultaneously using different processors. Other computers use timesharing, a system where a single processor moves among more than one task, making progress on each in turn and maintaining the context of each. Concurrency and Threads The more programs interact with the real world, in such ways as monitoring sensors or awaiting commands, the more important concurrency becomes. In this lecture we ll take a brief look at some of the major issues with concurrency, and the facilities Java offers to deal with them. You ll learn much more about concurrency in CMPSCI 230 and 377. Runnable and Thread The Runnable interface requires a single public method called run. The Thread class has a constructor that takes one argument of type Runnable. If we create a Thread object using a Runnable, we can then start the thread, at which point the Runnable s run method starts processing in parallel with the main thread. We can later interrupt the thread. 1

A Runnable Example public class Counter { private int count ; public Counter () { count = 0; } public void increment () { count += 1; } public String tostring () { return " Count is :\ t" + count ; } } public class Increase implements Runnable { private Counter c; private int amount ; public Increase ( Counter c, int amount ) { this.c = c; this. amount = amount ; } public void run () { for ( int i = 1; i <= amount ; i += 1) { c. increment (); } } } A Runnable Example This is the simplest way to run an Increase operation, in the main thread just as we would run anything else. The count field of c is increased to 10000 and the output is thus "Count is: 10000". public class Demo01 { public static void main ( String [] args ) { Runnable r = new Increase (c, 10000); r. run (); Clicker Question #1 What is the output of this application? public class Clicker1 { public static void main ( String [] args ) { Runnable r1 = new Increase (c, 10000); Runnable r2 = new Increase (c, -5000); r1.run (); r2.run (); A. an exception B. "Count is: 0" C. "Count is: 5000" D. "Count is: 10000" 2

Using Multiple Threads public class Demo02 { public static void main ( String [] args ) { Runnable r = new Increase (c, 10000); Thread t = new Thread ( r); t. start (); // note DJW typos You might think we get 10000 again, but on various trials John got numbers ranging from 91 to 603. (The behavior is non-deterministic!) The issue is that the Increase operation goes on in parallel with the main thread, and it only gets so far before the main thread prints c. Joining Two Threads public class Demo03 { public static void main ( String [] throws InterruptedException args ) { Runnable r = new Increase (c, 10000); Thread t = new Thread ( r); t. start (); t. join (); This time we do get 10000, because the join method suspends the main thread until the new thread is finished. So we only reach the print statement after the Increase is finished. Interference public class Demo04 { public static void main ( String [] args ) throws InterruptedException { Runnable r1 = new Increase (c, 5000); Runnable r2 = new Increase (c, 5000); Thread t1 = new Thread ( r1 ); Thread t2 = new Thread ( r2 ); t1. start (); t2. start (); t1. join (); t2. join (); Increasing c by 5000 twice ought to give us 10000 again. But on John s first five trials the results were 7426, 7438, 6898, 7923, and 6595. Why? Interference The problem here is interference between the threads. Both threads are trying to access the same variable count, by reading it, increasing it by 1, and writing it back. 3

Suppose that t1 reads the value 2317, then t2 reads 2317 before t1 writes back. Then t1 writes back 2318, and t2 also writes 2318. There were two attempts to increment the variable, but it only went up by one. Clicker Question #2 In the previous example, what happens if several increments by t1 happen between the read step of a t2 increment and its write step? A. All of them work, but the t2 one doesn t. B. None of the t1 increments have any effect. C. Only the last t1 increment works. D. An exception is thrown. Interference When does this happen? It depends on the exact timing of the read and write operations of the two threads. These are governed by the operating system, which is timesharing the processor or processors among the threads. Exactly what happens may well depend on the other loads on the processor, which is why we get the nondeterministic behavior. Synchronization We can t have this sort of thing happening whenever two different processes are sharing a resource. The basic idea to avoid the problem is to make sure that only one process has permission to access the resource at one time. In a hardware system, we might have a physical token that a process needs to have to get at the resource, and pass the token among the processes. Synchronization Fortunately Java lets us coordinate the processes at a higher level of abstraction, through a mechanism called method-level synchronization. We create a new class SyncCounter that is identical to Counter except for one thing: The method increment is declared to be synchronized. We then make a new class SyncIncrease that uses SyncCounter but has no other changes. 4

Synchronized Code public class SyncCounter { private int count ; public SyncCounter () { count = 0; } public synchronized void increment () { count += 1; } public String tostring () { return " Count is :\ t" + count ; } } public class SyncIncrease implements Runnable { private SyncCounter c; private int amount ; public SyncIncrease ( SyncCounter c, int amount ) { this.c = c; this. amount = amount ; } public void run () { for ( int i = 1; i <= amount ; i ++) { c. increment (); } } } Synchronization public class Demo05 { public static void main ( String [] args ) throws InterruptedException { SyncCounter c = new SyncCounter (); Runnable r1 = new SyncIncrease (c, 5000); Runnable r2 = new SyncIncrease (c, 5000); Thread t1 = new Thread ( r1 ); Thread t2 = new Thread ( r2 ); t1. start (); t2. start (); t1. join (); t2. join (); This version consistently prints 10000. What s different is that the increment method now plays nicely with other copies of itself, waiting for them to finish before going on. Synchronized Queues Queues are often shared among multiple processes. For example, client processes might put their requests on a queue for server processes to take off and satisfy. We would hate for an element to be put on the queue and never come off, or to come off twice. Interference among processes, like we have just seen, could easily cause this to happen, or cause the queue to throw an exception. Clicker Question #3 Suppose q is the array of an array-based queue, and one thread tries to enqueue(x) at about the same time as another thread tries to enqueue(y). The rear index is originally r. Which of these is not possible? A. x goes in position r+1, y in r+2 5

B. position r+1 is null, x goes in r+2 C. y goes in r+1, position r+2 is null D. all three of the results above are possible Synchronized Queue Example DJW have an example on pages 348-352 using the SyncCounter class. They have a new version of Increase that takes a Queue<Integer> as a parameter, and runs by taking integers off the queue and adding them to the counter, until the queue is empty. Their Demo06 class fills a queue with the numbers from 1 to 100, then creates two of these Increase processes to together empty the queue and add its members to a common SyncCounter. Synchronized Queue Example This works most but not all of the time. In their trials they got the correct answer of 5050 the first ten times, but the eleventh time got 4980 and the sixteenth time threw a NullPointerException. They fix this by writing a new class called SyncArrayBndQueue that has the word synchronized on its methods. All the methods then play nicely with one another. Queues in java.util Remember that Queue in the Collections package is an interface, implemented by nine different classes. Some of these classes are thread-safe, meaning that its operations are synchronized to prevent interference among them. The older Java classes like Vector are thread-safe, but modern Java offers cheaper, simpler unsynchronized classes like ArrayList, that may be used in the many situations where there aren t competing threads, as well as specific thread-safe classes. Average Waiting Time Queues are perhaps most commonly used to simulate real-world waiting situations. DJW offer a case study that allows a user to compare the average waiting times for customers when varying numbers of servers are available, each with its own queue. More servers cost more money, but customers are happier with shorter waiting times. 6

Exploring the tradeoffs in simulation is cheaper than running real-world experiments. But the simulation is only as good as its model of customer and server behavior. Average Waiting Time Different customers take different amounts of time to be served, and arrive for service with different intervals of time between them. An easy way to get such a variation is to use a Random object to generate numbers uniformly, within given ranges, for the service times and the intervals. The ranges might be based on actual experimental data DJW s simulator allows the user to provide the maximum and minimum service times and interval times. The Randomized Simulation The Simulation class will create the customers and queues, run the experiment, and report the results. A Customer object has an arrival time and a service time on its creation, and will have a finish time assigned during the simulation. We can calculate how long the Customer was waiting in the queue our output will be the average waiting time for the set of customers. The Randomized Simulation (continued) We ll need a CustomerGenerator class to generate these objects using a Random object. A Queue will correspond to each server. When a customer arrives, she will enter the shortest available queue (the one with the fewest customers in it). The Randomized Simulation (continued) The server will dequeue a customer when it finishes with the previous one, unless its queue is empty. The dequeued customer gets a finish time, computed by adding her service time to the time she is dequeued. But our existing queue classes actually won t suffice to model the queues we want. 7

The GlassQueue Class public class GlassQueue <T > extends LinkedUnbndQueue <T> { public int size () { return numelements ; } public T peekfront () { return head. getdata (); } public T peekrear () { return tail. getdata (); } } This is an example of the use of inheritance. In the case study, we want a queue that is able to report its size and to give pointers to its front and rear elements. (DJW call this a glass queue because it is transparent.) Rather than write a new class repeating the old code, we can extend the existing class. Clicker Question #4 public class GlassQueue <T > extends LinkedUnbndQueue <T> { public int size () { return numelements ; } public T peekfront () { return head. getdata (); } public T peekrear () { return tail. getdata (); } } Why can this class s code access the fields numelements, head, and tail? A. they are public fields B. they are protected fields of the superclass C. it can t because they are private fields of the superclass this code won t compile D. they are private fields but it doesn t matter 8