On execution, class Main might not display all of the four string values passed to ProcessData
constructors at lines 18 and 19.
How can you fix this situation?.
1. import java.util.*; 2. class Admission{ 3. static int id; 4. static Map<Integer, String> results = new HashMap<>(); 5. static int getNextId() {return ++id; } 6. static void qualify(Integer i, String s) {results.put(i, s);} 7. }//w w w .j a va2 s.com 8. class ProcessData extends Thread{ 9. List<String> list; 10. ProcessData(String[] val) {list = Arrays.asList(val);} 11. public void run() { 12. for (String item : list) 13. Admission.qualify(Admission.getNextId(), item); 14. } 15. } 16. class Main { 17. public static void main(String args[]) throws Exception { 18. ProcessData thread1 = new ProcessData( new String[]{"Paul", "value"}); 19. ProcessData thread2 = new ProcessData( new String[]{"value", "Harry"}); 20. thread1.start(); thread2.start(); 21. thread1.join(); thread2.join(); 22. for (String name : Admission.results.values()) 23. System.out.println(name); 24. } 25. }
getNextId()
method as synchronized at line 5getNextId()
and qualify methods as synchronized at lines 5 and 6c
The variable results, a hash map, stores unique keys.
Concurrent access to the unsynchronized getNextId()
can return the same ID values if it's accessed concurrently by multiple threads.
This can lead to overriding values for the same keys in a hash map.
So getNextId()
should be declared as a synchronized method at line 5.
Method qualify()
must also be declared as a synchronized method to make Map results thread safe; concurrent updates to a Map can result in overriding values.
Internally, a hash map uses hash values of its keys to determine in which bucket it should add a value.
When a hash map adds multiple values to a bucket, it links them so that it can retrieve all the values for a bucket value.
But concurrent modification of a Map object might report an empty bucket to multiple threads and so no linking will happen between the values added to the same bucket.
This can lead to untraceable values.