Advanced MEIC. (Lesson #18)

Similar documents
The Java Memory Model

Sharing Objects Ch. 3

Advanced concurrent programming in Java Shared objects

Atomicity via Source-to-Source Translation

Threads and Java Memory Model

CMSC 433 Spring 2013 Exam 1

Introduction to Locks. Intrinsic Locks

Safety SPL/2010 SPL/20 1

System Programming. Practical Session 4: Threads and Concurrency / Safety

The Java Memory Model

The New Java Technology Memory Model

Java Memory Model. Jian Cao. Department of Electrical and Computer Engineering Rice University. Sep 22, 2016

The Java Memory Model

Atomicity CS 2110 Fall 2017

Readings for This Lecture

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

Announcements for the Class

NON-BLOCKING DATA STRUCTURES AND TRANSACTIONAL MEMORY. Tim Harris, 17 November 2017

COMP 401 Spring 2013 Midterm 1

Cache Coherence and Atomic Operations in Hardware

C++ Memory Model. Don t believe everything you read (from shared memory)

Synchronization. Announcements. Concurrent Programs. Race Conditions. Race Conditions 11/9/17. Purpose of this lecture. A8 released today, Due: 11/21

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

Foundations of the C++ Concurrency Memory Model

Lecture 16: Thread Safety in Java

CMSC 433 Programming Language Technologies and Paradigms. Spring 2013

CMSC 433 Section 0101 Fall 2012 Midterm Exam #1

Recap. Contents. Reenterancy of synchronized. Explicit Locks: ReentrantLock. Reenterancy of synchronise (ctd) Advanced Thread programming.

Audience. Revising the Java Thread/Memory Model. Java Thread Specification. Revising the Thread Spec. Proposed Changes. When s the JSR?

Synchronization Lecture 23 Fall 2017

NON-BLOCKING DATA STRUCTURES AND TRANSACTIONAL MEMORY. Tim Harris, 31 October 2012

Monitors; Software Transactional Memory

MultiJav: A Distributed Shared Memory System Based on Multiple Java Virtual Machines. MultiJav: Introduction

Java Threads Vs Processes. CS Concurrent Programming. Java Threads. What can a thread do? Java Concurrency

Quis Custodiet Ipsos Custodes The Java memory model

Sharing Objects. Java and Android Concurrency.

Getter and Setter Methods

Learning from Bad Examples. CSCI 5828: Foundations of Software Engineering Lecture 25 11/18/2014

+ Today. Lecture 26: Concurrency 3/31/14. n Reading. n Objectives. n Announcements. n P&C Section 7. n Race conditions.

A Deterministic Concurrent Language for Embedded Systems

Multithreading and Interactive Programs

Shared Mutable State SWEN-220

Thread Safety. Review. Today o Confinement o Threadsafe datatypes Required reading. Concurrency Wrapper Collections

Synchronization SPL/2010 SPL/20 1

Recitation 3 Class and Objects

Types for Precise Thread Interference

The Java Memory Model

CS5460: Operating Systems

11/19/2013. Imperative programs

Consistency: Relaxed. SWE 622, Spring 2017 Distributed Software Engineering

Programming Language Concepts: Lecture 2

Runtime Atomicity Analysis of Multi-threaded Programs

Formal Verification Techniques for GPU Kernels Lecture 1

Synchronising Threads

Design of Thread-Safe Classes

Concurrency in Object Oriented Programs 1. Object-Oriented Software Development COMP4001 CSE UNSW Sydney Lecturer: John Potter

Synchronizing the Asynchronous

Section 5: Thread Synchronization

JSR-133: Java TM Memory Model and Thread Specification

NON-BLOCKING DATA STRUCTURES AND TRANSACTIONAL MEMORY. Tim Harris, 21 November 2014

A Deterministic Concurrent Language for Embedded Systems

CS61B Lecture #7. Announcements:

Agenda. Highlight issues with multi threaded programming Introduce thread synchronization primitives Introduce thread safe collections

Monitors; Software Transactional Memory

The Object Concept. Object-Oriented Programming Spring 2015

Need for synchronization: If threads comprise parts of our software systems, then they must communicate.

Synchronization via Transactions

<Insert Picture Here> Revisting Condition Variables and Transactions

Implementing caches. Example. Client. N. America. Client System + Caches. Asia. Client. Africa. Client. Client. Client. Client. Client.

RCU in the Linux Kernel: One Decade Later

Notes on Chapter Three

Composable Shared Memory Transactions Lecture 20-2

Identity, State and Values

Synchronization: Basics

Session 20 Data Sharing Session 20 Data Sharing & Cookies

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

Consistency. CS 475, Spring 2018 Concurrent & Distributed Systems

Overview of Lecture 4. Memory Models, Atomicity & Performance. Ben-Ari Concurrency Model. Dekker s Algorithm 4

G Programming Languages Spring 2010 Lecture 13. Robert Grimm, New York University

What is the return type of getnameofmonth?

Effective Data-Race Detection for the Kernel

Problems with Concurrency

Problems with Concurrency. February 19, 2014

3/25/14. Lecture 25: Concurrency. + Today. n Reading. n P&C Section 6. n Objectives. n Concurrency

Programming Paradigms for Concurrency Lecture 3 Concurrent Objects

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

Java Semaphore (Part 1)

Mohamed M. Saad & Binoy Ravindran

Programming Language Concepts: Lecture 2

Synchronization: Basics

Programming II (CS300)

Concurrency WS 2010/2011 The Java Memory Model

CMSC 433 Programming Language Technologies and Paradigms. Composing Objects

G51PGP Programming Paradigms. Lecture 009 Concurrency, exceptions

Multithreading and Interactive Programs

Persistent Data Structures and Managed References

Lecture 17: Sharing Objects in Java

Exercise Session Week 8

CS510 Advanced Topics in Concurrency. Jonathan Walpole

Scala. Introduction. Scala

Transcription:

Advanced Programming @ MEIC (Lesson #18)

Last class Data races Java Memory Model No out-of-thin-air values Data-race free programs behave as expected

Today Finish with the Java Memory Model Introduction to concurrent objects How to implement them?

Java Memory Model primitives synchronized blocks volatile fields final fields

Java Memory Model primitives synchronized blocks volatile fields final fields

Thread-safety and Immutable Objects João Cachopo

java.util.hashtable vs java.util.hashmap

What about j.u.c.concurrenthashmap?

What is thread-safety?

A piece of code is thread-safe if it can be used in a multi-threaded environment -- Wikipedia

An object is thread-safe if it can be used in a multi-threaded environment if it can be used?

public class Counter { private int count = 0; public void inc() { count++; public void getcount() { return count; Can this be used in a multi-threaded environment?

public class Counter { private int count = 0; public void inc() { count++; public void getcount() { return count; Yes, but not with correct behavior...

When can we say that a concurrent object is correct?

When can we say that a sequential object is correct?

Operations of a correct sequential object behave in a certain way

For instance, incrementing the counter twice and asking the count value should return 2

Does the same happen if the counter is used by multiple threads?

public class Counter { private int count = 0; public void inc() { count++; public void getcount() { return count;

Other problems may happen: e.g., object s invariants may break

We shall return to this later...

public class Counter { private int count = 0; public void inc() { count++; public void getcount() { return count; How to fix this?

public class Counter { private volatile int count = 0; public void inc() { count++; public void getcount() { return count; Does this work?

public class Counter { private volatile int count = 0; public void inc() { count++; public void getcount() { return count; volatile inc atomic

public class Counter { private int count = 0; public synchronized void inc() { count++; public void getcount() { return count; What about this?

public class Counter { private int count = 0; public synchronized void inc() { count++; // and this one needs it too? public void getcount() { return count; Do we have a data-race?

YES Thread T1 reads count Thread T2 writes to count No sync among them

public class Counter { private int count = 0; public synchronized void inc() { count++; // and this one needs it too? public void getcount() { return count; Does it matter?

If we want linearizability, yes! (Without sync, a thread repeatedly calling count may always get the same value, even if inc was called many times by other threads)

public class Counter { private volatile int count = 0; public synchronized void inc() { count++; // and this one needs it too? public void getcount() { return count; Does this solve it?

public class Counter { private volatile int count = 0; public synchronized void inc() { count++; // and this one needs it too? public void getcount() { return count; Yes! No data-races.

Immutable objects are thread-safe (even if they are shared through a data-race!)

What is an immutable object?

Informally: An immutable object is an object whose state cannot be changed after the object is created

How to create immutable objects in Java?

Don t allow them to change!

public class Date { int day; int month; int year; public Date(int d, int m, int y) { day = d; month = m; year = y; Is this OK?

Date d = new Date(1, 4, 2011); sharedvar = d; d.day = 3;

public class Date { int day; int month; int year; public Date(int d, int m, int y) { day = d; month = m; year = y; How to fix this?

public class Date { private int day; private int month; private int year; public Date(int d, int m, int y) {... public int day() { return day; public int month() { return month; public int year() { return year; // NOTE: no setters! Is it OK now?

Date d = new Date(1, 4, 2011); sharedvar = d; // normal write (data-race) // on another thread Date d = sharedvar; //normal read (data-race) if (d!= null) { int year = d.year(); //saw the new date object? Is there a problem?

Date d = new Date(1, 4, 2011); sharedvar = d; // normal write (data-race) // on another thread Date d = sharedvar; //normal read (data-race) if (d!= null) { //saw the new date object? int year = d.year(); //may return 0 Is there a problem?

public class Date { private int day; private int month; private int year; public Date(int d, int m, int y) {... public int day() { return day; public int month() { return month; public int year() { return year; // NOTE: no setters! How to fix it?

public class Date { private final int day; private final int month; private final int year; public Date(int d, int m, int y) {... public int day() { return day; public int month() { return month; public int year() { return year; // NOTE: no setters! The JMM to the rescue!

Date d = new Date(1, 4, 2011); sharedvar = d; // normal write (data-race) // on another thread Date d = sharedvar; //normal read (data-race) if (d!= null) { //saw the new date object? int year = d.year(); //always returns 2011

Using final is not enough...

public class Date { private final int day; private final int month; private final int year; public Date(int d, int m, int y) { day = d; month = m; year = y; // getters...

public class Date { private final int day; private final int month; private final int year; public Date(int d, int m, int y) { day = d; month = m; year = y; sharedvar = this; // let this escape // getters...

Date d = new Date(1, 4, 2011);

Date d = new Date(1, 4, 2011); // on another thread Date d = sharedvar; //normal read (data-race) if (d!= null) { //saw the new date object? int year = d.year(); //may return 0

The final guarantees work only after the constructor finishes

One last note about the final semantics

public class Foo { public int x; // no final here public Foo(int x) { this.x = x; public class Bar { private final Foo f; public Bar() { this.f = new Foo(3); public Foo foo() { return f;

sharedvar = new Bar(); //normal write (data-race) // on another thread Bar b = sharedvar; //normal read (data-race) if (b!= null) { int x = b.foo().x; //?? //saw the new bar object?

sharedvar = new Bar(); //normal write (data-race) // on another thread Bar b = sharedvar; //normal read (data-race) if (b!= null) { //saw the new bar object? int x = b.foo().x; //always returns 3

Other threads will see versions of any object or array referenced by final fields that are at least as up-to-date as the final fields are

References The Java Language Specification, Section 17.5: Final Field Semantics Immutable Objects (The Java Tutorials > Essential Classes > Concurrency)

Concurrent objects

public class Counter { private int count = 0; public void inc() { count++; public void getcount() { return count;

public class Counter { private int count = 0; public synchronized void inc() { count++; public synchronized void getcount() { return count;

public class Counter { private int count = 0; public synchronized void inc() { count++; public synchronized void getcount() { return count; Is this the only way?

Using a Software Transactional Memory

JVSTM

Software Transactional Memory as a Java library

public class VBox<E> { public VBox(E initial); public E get(); public void put(e newe);

public class VBox<E> { public VBox(E initial); public E get(); public void put(e newe); class Person { String name; String getname() { return name; void setname(string name) { this.name = name; class Person { final VBox<String> name = new VBox<String>(null); String getname() { return name.get(); void setname(string name) { this.name.put(name);

public class VBox<E> { public VBox(E initial); public E get(); public void put(e newe); Must be immutable! class Person { String name; String getname() { return name; void setname(string name) { this.name = name; class Person { final VBox<String> name = new VBox<String>(null); String getname() { return name.get(); void setname(string name) { this.name.put(name);

public class Transaction { public static void start(); public static void abort(); public static void commit();

public class Transaction { public static void start(); public static void abort(); public static void commit(); class SomeClass { @Atomic void swapnames(person p1, Person p2) { String tmp = p1.getname(); p1.setname(p2.getname); p2.setname(tmp);

public class Transaction { public static void start(); public static void abort(); public static void commit(); You should be using this class SomeClass { @Atomic void swapnames(person p1, Person p2) { String tmp = p1.getname(); p1.setname(p2.getname); p2.setname(tmp);

If using the @Atomic annotation: java jvstm.processatomicannotations \ <directory with all.class files>

public class Counter { private int count = 0; public void inc() { count++; public void getcount() { return count;

public class Counter { private final VBox<Integer> count = new VBox<Integer>(0); public void inc() { count++; public void getcount() { return count;

public class Counter { private final VBox<Integer> count = new VBox<Integer>(0); public void inc() { count.put(count.get() + 1); public void getcount() { return count.get();

public class Counter { private final VBox<Integer> count = new VBox<Integer>(0); @Atomic public void inc() { count.put(count.get() + 1); public void getcount() { return count.get();

First multi-version STM Designed for very large transactions and high read/write ratio

It is a lock-free STM

How to implement atomic operations without locks?

public class Counter { private int count = 0; public void inc() { count++; public void getcount() { return count;

public class Counter { private int count = 0; public void inc() { count++;...

public class Counter { private int count = 0; public void inc() { int c = count; int newc = c + 1; count = newc;...

public class Counter { private int count = 0; public void inc() { int c = count; // read int newc = c + 1; // do something count = newc; // update (write)...

public class Counter { private int count = 0; public void inc() { int c = count; // read int newc = c + 1; // do something count = newc; // update (write)... Only if count was not changed by another thread...

public class Counter { private int count = 0; public void inc() { int c = count; int newc = c + 1; CAS(count, c, newc);...

CAS = compare-and-set

CAS(var, old, new) if (var == old) { var = new; return true; else { return false;

CAS(var, old, new) if (var == old) { var = new; return true; else { return false; But, it is atomic!

public class Counter { private int count = 0; public void inc() { int c = count; int newc = c + 1; CAS(count, c, newc);... What s the problem?

public class Counter { private int count = 0; public void inc() { while (true) { int c = count; int newc = c + 1; if CAS(count, c, newc) return;...

public class Counter { private int count = 0; public void inc() { while (true) { int c = count; int newc = c + 1; if CAS(count, c, newc) return;... We can still do better...