У моего кода есть много потоков, выполняющих чтение-Update-Writes в общую хеш-карту без какой-либо синхронизации. Я работал так много раз с 1000 потоков, 1 млн. Итераций, поэтому я ожидаю, что окончательные значения для 4 ключей будут составлять около 250 м, но не точно, поскольку обновления/записи могут быть потеряны из -за нескольких потоков, которые читают одно и то же значение из -за чтения В то же время. < /p>
Однако, после многих испытаний, я вижу, что значения всегда 250 м, поэтому обновления не теряются. FWIW, я пишу это приложение для игрушек, чтобы сравнить его с тем, когда я использую Collections.synchronizedMap, однако мне нужно, чтобы это приложение не было провалившимся (чтобы показать состояние гонки), но он всегда дает результат без обновления.
Ключ: 0 Val: 250000000 < /p>
Ключ: 1 Val: 250000000
Ключ: 2 Val: 250000000
Ключ: 3 Val: 250000000
package threadsafecollections;
import java.util.HashMap;
import java.util.Map;
public class SynchronizedCollectionTask {
public static int NUM_THREADS = 1000;
public static class ReadUpdateWrite implements Runnable {
Map map;
int threadId;
public static int NUM_ITERATIONS = 1000000;
ReadUpdateWrite(Map m, int threadId) {
this.map = m;
this.threadId = threadId;
}
@Override
public void run() {
for (int i = 0; i < NUM_ITERATIONS; i++) {
int key = threadId % 4;
Integer val = this.map.get(key);
map.put(key, val == null ? 1 : val + 1);
}
// At this point I expect each key in map to have value of CLOSE TO
// numThreads * NUM_ITERATIONS / 4 = 250M. I expect some threads to have
// both read the same value, and therefore "miss" a write. For example,
// thread 4 and 8 both read key = 0 and see value = 3. Now both thread
// increment value to 4, instead of one thread incrementing to 4 and the
// other incrementing to 5.
}
}
public static void main(String[] args) throws InterruptedException {
Map sharedMap = new HashMap();
// Initialize threads
Thread[] readers = new Thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
readers = new Thread(new ReadUpdateWrite(sharedMap, i));
}
long start = System.currentTimeMillis();
// Start threads
for (int i = 0; i < NUM_THREADS; i++) {
readers.run();
}
// Join threads
for (int i = 0; i < NUM_THREADS; i++) {
readers.join();
}
long end = System.currentTimeMillis();
System.out.println("Work took: " + (end - start) / 1000D);
for (int key : sharedMap.keySet()) {
System.out.println ("Key: " + key + " val: " + sharedMap.get(key));
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/437 ... -java-code