MCPcopy Index your code
hub / github.com/oshi/oshi / run

Method run

oshi-core/src/test/java/oshi/util/MemoizerTest.java:109–173  ·  view source on GitHub ↗
(final long iterationDurationNanos, final long ttlNanos)

Source from the content-addressed store, hash-verified

107 }
108
109 private void run(final long iterationDurationNanos, final long ttlNanos) throws Throwable {
110 final Supplier<Long> s = new Supplier<Long>() {
111 private long value;
112
113 // this method is not thread-safe, the returned value of the counter may go down
114 // if this method is called concurrently from different threads
115 @Override
116 public Long get() {
117 return ++value;
118 }
119 };
120 // The memoizer we are testing
121 final Supplier<Long> m = memoize(s, ttlNanos);
122 // Hold the results until all threads terminate
123 final Collection<Future<Void>> results = new ArrayList<>();
124 // Mark the start time, end after iterationDuration
125 final long beginNanos = System.nanoTime();
126 for (int tid = 0; tid < numberOfThreads; tid++) {
127 results.add(ex.submit(() -> {
128 // First read from the memoizer. Only one thread will win this race to increment
129 // 0 to 1, but all threads should read at least 1, if not increment further
130 Long previousValue = m.get();
131 assertThat("previousValue should not be null", previousValue, is(notNullValue()));
132 assertThat("previousValue should be greater than zero", previousValue, is(greaterThan(0L)));
133 // Memoizer's ttl was set during previous call (for race winning thread) or
134 // earlier (for losing threads) but if we delay for at least ttl from now, we
135 // are sure to get at least one increment if ttl is nonnegative
136 final long firstSupplierCallNanos = System.nanoTime();
137 // using guaranteedIteration this loop is guaranteed to be executed at
138 // least once regardless of whether we have exceeded time delays
139 boolean guaranteedIteration = false;
140 long now;
141 while ((now = System.nanoTime()) - beginNanos < iterationDurationNanos
142 || now - firstSupplierCallNanos < ttlNanos || (guaranteedIteration = !guaranteedIteration)) {
143 // guaranteedIteration will only be set true when the first two timing
144 // conditions are false, which will allow at least one iteration. After that
145 // final iteration the boolean will toggle false again to stop the loop.
146 if (Thread.currentThread().isInterrupted()) {
147 throw new InterruptedException();
148 }
149 final Long newValue = m.get();
150 // check that we never get uninitialized
151 assertThat("newValue should not be null", newValue, is(notNullValue()));
152 // check that the counter never goes down // value
153 assertThat("newValue shuld be larger", newValue, is(not(lessThan(previousValue))));
154 previousValue = newValue;
155 }
156 return null;
157 }));
158 }
159 /*
160 * Make sure all the submitted tasks finished correctly
161 */
162 finishAllThreads(results);
163 /*
164 * All the writes to s.value field happened-before this read because of all the
165 * result.get() invocations, so it holds the final/max value returned by any
166 * thread. We cannot access s.value but it's private, and s.get() will increment

Callers 1

getMethod · 0.95

Calls 5

finishAllThreadsMethod · 0.95
testIncrementCountsMethod · 0.95
memoizeMethod · 0.80
assertThatMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected