Difference between revisions of "Atomicity"
Line 16: | Line 16: | ||
: ''get then put is not atomic<br>call [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#compute-K-java.util.function.BiFunction- compute]<br>call [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#compute-K-java.util.function.BiFunction- compute]<br>use [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html ConcurrentHashMap]<br>use [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html ConcurrentHashMap]<br>or say shoot!<br>or say shoot!'' | : ''get then put is not atomic<br>call [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#compute-K-java.util.function.BiFunction- compute]<br>call [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#compute-K-java.util.function.BiFunction- compute]<br>use [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html ConcurrentHashMap]<br>use [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html ConcurrentHashMap]<br>or say shoot!<br>or say shoot!'' | ||
+ | =Studio= | ||
+ | ==SuspectWordCount== | ||
+ | {{Warning|Do NOT use synchronized here. ConcurrentMaps are already thread safe.}} | ||
− | |||
fix the code to remove the atomicity race. | fix the code to remove the atomicity race. | ||
+ | {{CodeToDebug|SuspectWordCount|countWords|atomicity.wordcount.studio}} | ||
+ | {{Parallel|public static Map<String, Integer> countWords(Iterable<String> words)}} | ||
− | =StockPortfolio= | + | ==StockPortfolio== |
− | =Course= | + | ==Course== |
− | =Code To Fix= | + | ===Code To Fix=== |
{{Warning|Do NOT use synchronized here. ConcurrentMaps are already thread safe.}} | {{Warning|Do NOT use synchronized here. ConcurrentMaps are already thread safe.}} | ||
− | == | + | ====Transfer==== |
− | |||
− | |||
− | |||
− | == | ||
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 15:52, 8 April 2020
Contents
Motivation
Many race conditions can be prevented by proper encapsulation avoiding check-then-write and read-then-modify-then-write in non-atomically.
Background
Take a look at the synchronized and lock sections of the reference page
Song to Recall
- get then put is not atomic
call compute
call compute
use ConcurrentHashMap
use ConcurrentHashMap
or say shoot!
or say shoot!
Studio
SuspectWordCount
Warning:Do NOT use synchronized here. ConcurrentMaps are already thread safe. |
fix the code to remove the atomicity race.
class: | SuspectWordCount.java | |
methods: | countWords | |
package: | atomicity.wordcount.studio | |
source folder: | student/src/main/java |
method: public static Map<String, Integer> countWords(Iterable<String> words)
(parallel implementation required)
StockPortfolio
Course
Code To Fix
Warning:Do NOT use synchronized here. ConcurrentMaps are already thread safe. |
Transfer
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; }
class: | StockPortfolio.java | |
methods: | transfer | |
package: | atomicity.stockportfolio.studio | |
source folder: | student/src/main/java |
method: private int transfer(String listingSymbol, int deltaShareCount)
(thread-safe required)
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.)
Code To Investigate
Warning:Although the code below is technically thread-safe, it offers check-then-act usage which leads to atomicity races. |
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
We will build a thread-safe Course
class with methods which do not lead clients towards atomicity races.
class: | Course.java | |
methods: | addIfSpace drop |
|
package: | atomicity.course.studio | |
source folder: | student/src/main/java |
method: public boolean addIfSpace(Student student)
(thread-safe required)
Adds the student if there is space under the limit specified to the constructor and returns whether or not the add actually occurred.
NOTE: Must be thread safe.
method: public boolean drop(Student student)
(thread-safe required)
Removes the student from the course if the student was enrolled (the remove method returns just the status you need).
NOTE: Must be thread safe.
Testing Your Solution
Correctness
class: | AtomicityTestSuite.java | |
package: | atomicity | |
source folder: | testing/src/test/java |
class: WordCountAtomicityTestSuite.java package: atomicity.wordcount.studio source folder: testing/src/test/java class: StockPortfolioAtomicityTestSuite.java package: atomicity.stockportfolio.studio source folder: testing/src/test/java class: CourseAtomicityTestSuite.java package: atomicity.course.studio source folder: testing/src/test/java