Atomicity

From CSE231 Wiki
Jump to navigation Jump to search

Motivation

Many race conditions can be prevented by proper encapsulation avoiding check-then-write and read-then-modify-then-write in non-atomically.

Background

Concurrency Tutorial

Synchronized Methods
Intrinsic Locks

ConcurrentMap

compute

Code To Investigate

YUCK

class: CheckThenActCourse.java DEMO: Java.png
methods: isSpaceRemaining
add
drop
package: atomicity.course.studio
source folder: src//java
public class CheckThenActCourse {
	private final Collection<Student> students;
	private final int limit;

	public CheckThenActCourse(int limit, Supplier<Collection<Student>> collectionSupplier) {
		this.students = collectionSupplier.get();
		this.limit = limit;
	}

	public int getLimit() {
		return this.limit;
	}

	public boolean isSpaceRemaining() {
		synchronized (this.students) {
			return this.students.size() < this.limit;
		}
	}

	public void add(Student student) {
		synchronized (this.students) {
			this.students.add(student);
		}
	}

	public boolean drop(Student student) {
		synchronized (this.students) {
			return this.students.remove(student);
		}
	}
}

Code To Implement

class: Course.java Java.png
methods: addIfSpace
drop
package: atomicity.course.studio
source folder: student/src/main/java

method: public boolean addIfSpace(Student student) Sequential.svg (sequential implementation only)

method: public boolean drop(Student student) Sequential.svg (sequential implementation only)

Code To Fix

For this part of the studio we are presented with broken code. Despite using a thread-safe concurrent map:

private final ConcurrentMap<String, Integer> map;

it suffers from an atomicity race:

private int transfer(String listingSymbol, int deltaShareCount) {
	Integer oldValue = this.map.get(listingSymbol);
	Integer newValue;
	if (oldValue != null) {
		newValue = oldValue + deltaShareCount;
	} else {
		newValue = deltaShareCount;
	}
	this.map.put(listingSymbol, newValue);
	return newValue;
}

Recalling the song:

get then put is not atomic
call compute
call compute
use ConcurrentHashMap
use ConcurrentHashMap
or say shoot!
or say shoot!

fix this code.

class: StockPortfolio.java Java.png
methods: transfer
package: atomicity.stockportfolio.studio
source folder: student/src/main/java

Testing Your Solution

Correctness

class: AtomicityTestSuite.java Junit.png
package: atomicity
source folder: testing/src/test/java