傻走部进一步推荐以下多线程替代方案:
package test;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
private static final int NUMBER_WALKS = 100;
private static final int NUMBER_STEPS = 500;
private static class Counter implements Runnable {
private final AtomicInteger counter;
private final ConcurrentSkipListMap<Integer, Integer> totals;
public Counter(final AtomicInteger counter, final ConcurrentSkipListMap<Integer, Integer> totals) {
this.counter = counter;
this.totals = totals;
}
@Override
public void run() {
int result;
Integer oldValue;
while ((Thread.currentThread().isInterrupted() == false) && (this.counter.decrementAndGet() >= 0)) {
result = 0;
for (int i = 0; i < NUMBER_STEPS; ++i) {
result += ThreadLocalRandom.current().nextInt(2) == 0 ? -1 : 1;
}
oldValue = totals.putIfAbsent(result, 1);
if (oldValue != null) {
while (totals.replace(result, oldValue, oldValue + 1) == false) {
oldValue = totals.get(result);
}
}
}
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
final AtomicInteger counter = new AtomicInteger(NUMBER_WALKS);
final ConcurrentSkipListMap<Integer, Integer> totals = new ConcurrentSkipListMap<>();
final int numCPUs = Runtime.getRuntime().availableProcessors();
final ExecutorService executor = Executors.newFixedThreadPool(numCPUs);
for (int i = 0; i < numCPUs; ++i) {
executor.submit(new Counter(counter, totals));
}
executor.shutdown();
if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
for (Integer key : totals.keySet()) {
System.out.println(String.format("%3d was called %3d times.", key, totals.get(key)));
}
} else {
executor.shutdownNow();
System.err.println("Executor did not terminate as expected.");
}
}
}