Lecture 24 Concurrency 2 (D&D 23) Date.

Slides:



Advertisements
Similar presentations
Concurrency Important and difficult (Ada slides copied from Ed Schonberg)
Advertisements

Ade Azurat, Advanced Programming 2004 (Based on LYS Stefanus’s slides) Advanced Programming 2004, Based on LYS Stefanus’s slides Slide 2.1 Multithreading.
Multithreaded Programs in Java. Tasks and Threads A task is an abstraction of a series of steps – Might be done in a separate thread – Java libraries.
Concurrency 101 Shared state. Part 1: General Concepts 2.
CS 11 java track: lecture 7 This week: Web tutorial:
Threading Part 2 CS221 – 4/22/09. Where We Left Off Simple Threads Program: – Start a worker thread from the Main thread – Worker thread prints messages.
CS220 Software Development Lecture: Multi-threading A. O’Riordan, 2009.
Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.
Synchronization in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Threads II. Review A thread is a single flow of control through a program Java is multithreaded—several threads may be executing “simultaneously” If you.
Java How to Program, 9/e CET 3640 Professor: Dr. Reyes Álamo © Copyright by Pearson Education, Inc. All Rights Reserved.
Multithreading.
Parallel Processing (CS526) Spring 2012(Week 8).  Thread Status.  Synchronization in Shared Memory Programming(Java threads ) ◦ Locks ◦ Barriars.
1 CSCD 330 Network Programming Lecture 13 More Client-Server Programming Sometime in 2014 Reading: References at end of Lecture.
1 Thread II Slides courtesy of Dr. Nilanjan Banerjee.
Object Oriented Analysis & Design SDL Threads. Contents 2  Processes  Thread Concepts  Creating threads  Critical sections  Synchronizing threads.
111 © 2002, Cisco Systems, Inc. All rights reserved.
Multithreading : synchronization. Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.2 Solving the Race Condition Problem A thread must.
Internet Software Development Controlling Threads Paul J Krause.
Threading Eriq Muhammad Adams J
Synchronized and Monitors. synchronized is a Java keyword to denote a block of code which must be executed atomically (uninterrupted). It can be applied.
CSC321 Concurrent Programming: §5 Monitors 1 Section 5 Monitors.
Synchronizing threads, thread pools, etc.
Multithreading in Java Sameer Singh Chauhan Lecturer, I. T. Dept., SVIT, Vasad.
Advanced Concurrency Topics Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.
COMPSCI 230 S2C 2015 Software Design and Construction Synchronization (cont.) Lecture 4 of Theme C.
Threads. Objectives You must be able to answer the following questions –What code does a thread execute? –What states can a thread be in? –How does a.
Comunication&Synchronization threads 1 Programación Concurrente Benemérita Universidad Autónoma de Puebla Facultad de Ciencias de la Computación Comunicación.
Threads in Java Threads Introduction: After completing this chapter, you will be able to code your own thread, control them efficiently without.
Threads b A thread is a flow of control in a program. b The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
1 G53SRP: Java Concurrency Control (2) – wait/notify Chris Greenhalgh School of Computer Science.
CSC CSC 143 Threads. CSC Introducing Threads  A thread is a flow of control within a program  A piece of code that runs on its own. The.
Concurrency (Threads) Threads allow you to do tasks in parallel. In an unthreaded program, you code is executed procedurally from start to finish. In a.
Software Design 13.1 From controller to threads l Threads are lightweight processes (what’s a process?)  Threads are part of a single program, share state.
Concurrent Programming in Java Based on Notes by J. Johns (based on Java in a Nutshell, Learning Java) Also Java Tutorial, Concurrent Programming in Java.
Lecture 5 Page 1 CS 111 Summer 2013 Bounded Buffers A higher level abstraction than shared domains or simple messages But not quite as high level as RPC.
Java Thread Programming
Race Conditions & Synchronization
Principles of Software Development
Race Conditions & Synchronization
CSCD 330 Network Programming
Multithreading / Concurrency
Multi Threading.
Java Concurrency.
Atomic Operations in Hardware
Lecture 25 More Synchronized Data and Producer/Consumer Relationship
Lecture 21 Concurrency Introduction
Threads Chate Patanothai.
Multithreaded Programming in Java
Synchronization Lecture 23 – Fall 2017.
Condition Variables and Producer/Consumer
Condition Variables and Producer/Consumer
Race Conditions & Synchronization
Producer-Consumer Problem
Multithreading.
Concurrency in Java Last Updated: Fall 2010 Paul Ammann SWE 619.
Dr. Mustafa Cem Kasapbaşı
Monitors Chapter 7.
Multithreading in java.
NETWORK PROGRAMMING CNET 441
CSE 153 Design of Operating Systems Winter 19
Threads and Multithreading
CSCD 330 Network Programming
Lecture 19 Threads CSE /6/2019.
Software Engineering and Architecture
Don Porter Portions courtesy Emmett Witchel
CMSC 202 Threads.
More concurrency issues
Java Chapter 3 (Estifanos Tilahun Mihret--Tech with Estif)
Synchronization and liveness
Presentation transcript:

Lecture 24 Concurrency 2 (D&D 23) Date

Goals By the end of this lesson, you should: Understand the implications of producer-consumer relationships Be able to use wait() and notifyAll() in order to synchronize threads across methods.

synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary The synchronized keyword lets us ensure that only one method at a time can enter the protected block of code, e.g., a method. This does not protect shared data from inconsistency. Consider a shared instance variable being accessed by two different synchronized methods. Even if each method can only be executed by one thread at a time, this still allows one thread to execute the first method and the other to execute the second method, at the same time. This means that the shared instance variable can be accessed by both threads, with potentially unwanted results.

synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary Often, this situation arises in the context of buffers. For example, a FIFO buffer (first-in-first-out) has data added to its end and removed from the front. FIFO buffers are also known as (simple) queues and are usually implemented as a linked list (-> COMPSCI105/107) FIFO buffers are often used with threaded applications: One thread adds data to the end of the queue, one thread reads the data from the front of the queue. Example: In an audio player, one thread reads audio data from disk. This thread typically blocks while it reads data from the disk and then writes a lot of data to the FIFO in big chunks at irregular times. The other thread reads data at regular intervals in small quantities off the front of the queue for immediate replay. Data in buffer Data added here Data read from here

synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary Data in buffer Data added here Data read from here Two problems can occur here: The reading thread may consume data faster than the writing thread is able to produce data, causing the buffer to run empty. The writing thread may produce data faster than the reading thread can consume it, causing the writing thread to overfill the buffer beyond capacity.

Library example synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary This is a simplified example of a producer-consumer relationship. Consider a library that owns a certain number of books. Each library patron may borrow a certain number of books. The patron keeps the books for a while and then returns them. The library cannot loan out more books than it owns. In other words: In real life, a patron can’t come and borrow more books than the library currently has on its shelves.

Library example synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary In a program: The number of books currently in the library is an int. Each patron is a thread. The library is an object shared by all patron threads. The library has methods for borrowing and returning books. These methods are called by the patrons, passing the number of books they wish to borrow or return. These methods are synchronized, meaning that only one patron thread at a time can borrow books, or return books. Note: Many, even all patrons, can hold borrowed books at any given time. They just can’t take them out simultaneously, or return them simultaneously. Each patron chooses the number of books to take out (a number smaller than the number of books that the library owns). The library patrons act as both consumers (they take books out) and producers (they bring books back) of data (books) in the buffer (the library).

The Library interface + class synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary // Common interface for the thread-safe and non-thread-safe // library classes public interface Library { public void borrowBooks(String borrower, int numberOfBooks); public void returnBooks(String borrower, int numberOfBooks); } Implementation (for now): public class NonThreadSafeLibrary implements Library { private int books = 40; public synchronized void borrowBooks(String patron, int numberToBorrow) { books -= numberToBorrow; System.out.println(patron + " borrowed " + numberToBorrow + " books"); System.out.println("Library has " + books); } public synchronized void returnBooks(String patron, int numberToReturn) { books += numberToReturn; System.out.println(patron + " returned " + numberToReturn + " books");

LibraryPatron class synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary import java.security.SecureRandom; public class LibraryPatron implements Runnable { private static final SecureRandom randomGenerator = new SecureRandom(); public String name; public Library library; public LibraryPatron(String name, Library library) { this.name = name; this.library = library; } public void run() { for (int i=0; i<20; i++) { // Borrow some books (up to 14) int numberOfBooks = randomGenerator.nextInt(15); library.borrowBooks(name, numberOfBooks); // Hang onto them for a while try { Thread.sleep(randomGenerator.nextInt(20)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // Return them library.returnBooks(name, numberOfBooks);

LibraryTest main() synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary public static void main(String[] args) { Library library = new NonThreadSafeLibrary(); LibraryPatron alice = new LibraryPatron("Alice", library); LibraryPatron bob = new LibraryPatron("Bob", library); LibraryPatron charlie = new LibraryPatron("Charlie", library); LibraryPatron donna = new LibraryPatron("Donna", library); LibraryPatron eve = new LibraryPatron("Eve", library); LibraryPatron fred = new LibraryPatron("Fred", library); ExecutorService es = Executors.newCachedThreadPool(); es.execute(alice); es.execute(bob); es.execute(charlie); es.execute(donna); es.execute(eve); es.execute(fred); es.shutdown(); }

Library test results synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary … Donna returned 5 books Library has 12 Donna borrowed 10 books Library has 2 Bob returned 6 books Library has 8 Bob borrowed 11 books Library has -3 Charlie returned 5 books Charlie borrowed 8 books Library has -6 Donna returned 10 books Library has 4 …

What can we do? synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary Normally: The library would ask a patron wait until books become available. The library would notify waiting patrons that books have become available. We can do the same here. Note: A patron would be told to wait() when they try and borrow books. Since only one patron can enter the borrowBooks() method at any time, only that patron can be told to wait. All other patrons are blocked until that patron has vacated borrowBooks(). The library could either notify() that patron specifically, or notifyAll() waiting patrons – in this case, it makes little difference because the only patron that does actually wait() is the one that executes borrowBooks().

The ThreadSafeLibrary class synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary public class ThreadSafeLibrary implements Library { private int books = 40; public synchronized void borrowBooks(String patron, int numberToBorrow) { // While the library is short of books, let the thread wait while (numberToBorrow > books) { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); books -= numberToBorrow; System.out.println(patron + " borrowed " + numberToBorrow + " books"); System.out.println("Library has " + books); public synchronized void returnBooks(String patron, int numberToReturn) { books += numberToReturn; System.out.println(patron + " returned " + numberToReturn + " books"); // Let all waiting threads know that we have had books come back in notifyAll(); Don’t forget to change the class in LibraryTest!

Is it really threadsafe? synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary Running our example with the “thread-safe” class will generally not cause problems. But: Consider the following two lines: Each of these involve reading the value of books, subtracting or adding the value of numberToBorrow or numberToReturn, and then saving the result back to books. This will generally happen very, very quickly. Which guarantee do we have that these operations are atomic, i.e., cannot be completed by two different threads at the same time? None. Could both threads read the number of books, with one thread then changing it upwards without the other knowing it? Unlikely, but yes. Have a look at the ReallyThreadSafeLibrary example for a solution. books -= numberToBorrow; books += numberToReturn;

Adding complexity synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary Consider adding an AcquisitionsLibrarian who occasionally adds books to the library, and a shelf capacity that the library cannot exceed. You could also add a Librarian tasked with throwing out old books on a regular basis. Challenge: Implement these classes. Will the library class remain thread-safe under these circumstances? E.g., what would happen if you had a separate method to dispose of books? What might happen if Librarian tried to dispose of books via this method, and a borrower thread took some out at the same time?

Notes synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary Terminology: A situation as in our incrementor example where threads use the value of a shared variable that may since have been updated by another thread is known as a dirty read. If several threads write to a variable an unsynchronized fashion, as in our incrementor and library examples, we have a race condition – the threads are in a “race” to write to the variable (and the thread scheduling, which we can’t predict, determines who “wins”) It’s possible for two threads to end up waiting such that neither cannot return to runnable state without notification from the other. This is called a deadlock. Topics we haven’t dealt with here but that are worth exploring (and which you’re ready to explore) include: timed waiting, explicit acquisition/release of locks, data structures that assist in multi-threading, etc.

What do we know synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary Thread write access to shared memory can lead to unpredictable behaviour of multi-threaded software. The use of synchronized in Java does not offer complete protection. A common scenario in which multiple threads access the same data is when a producer thread writes data to a buffer from which a consumer thread reads. This happens, e.g., in audio or video players where one thread reads the data from disk or network, and the other thread replays. This can result in buffer underruns or buffer overruns. We can tell a Java thread to wait(). This puts the thread into the waiting state. A waiting thread can be interrupted to resume execution. A call to the notify() method of the waiting thread object, or to notifyAll() interrupts the/all waiting thread(s) and causes it/them to return to runnable state. Writing truly thread-safe software is challenging!

Resources & Homework synchronized is not enough Producers and consumers: Library example Is it really threadsafe? Notes Summary https://docs.oracle.com/javase/tutorial/essential/concurrency/ https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html (wait(), notify(), notifyAll()) https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html D & D Chapter 23

Next Exam. Good luck everyone!