Motivation
Many race conditions can be prevented by proper encapsulation avoiding check-then-write and read-write-modify patterns.
Background
Concurrency Tutorial
- Synchronized Methods
- Intrinsic Locks
Code To Investigate
class: |
CheckThenActCourse.java |
DEMO: |
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 |
|
methods: |
addIfSpace drop |
package: |
atomicity.course.studio |
source folder: |
student/src/main/java |
method: public boolean addIfSpace(Student student)
(sequential implementation only)
method: public boolean drop(Student student)
(sequential implementation only)
Code To Fix
class: |
StockPortfolio.java |
|
methods: |
transfer |
package: |
atomicity.stockportfolio.studio |
source folder: |
student/src/main/java |
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;
}
Testing Your Solution
Correctness
class: |
AtomicityTestSuite.java |
|
package: |
atomicity |
source folder: |
testing/src/test/java |