Difference between revisions of "Atomicity"

From CSE231 Wiki
Jump to navigation Jump to search
Line 56: Line 56:
  
 
=Code To Fix=
 
=Code To Fix=
 +
{{Warning|Do NOT use synchronized here.  ConcurrentMap is already thread safe.}}
 +
 
For this part of the studio we are presented with broken code.  Despite using a thread-safe concurrent map:
 
For this part of the studio we are presented with broken code.  Despite using a thread-safe concurrent map:
  

Revision as of 22:12, 12 April 2018

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

Attention niels epting.svg Warning:Do NOT use synchronized here. ConcurrentMap is already thread safe.

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 the code to remove the atomicity race.

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

method: private int transfer(String listingSymbol, int deltaShareCount) Sequential.svg (sequential implementation only)

NOTE: do not be concerned about ConcurrentMap vs ConcurrentHashMap. The supplier's get method will return an instance of a thread-safe map. (It will, in fact, be an instance of ConcurrentHashMap.)

Testing Your Solution

Correctness

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