Scope.Thread and @Setup bug?
Aleksey Shipilev
shade at redhat.com
Wed Sep 28 07:20:47 UTC 2016
On 09/27/2016 08:19 PM, Lev Serebryakov wrote:
> On 27.09.2016 15:54, Aleksey Shipilev wrote:
>
>> It can even initialize after the shared @State(Benchmark) object:
>> http://hg.openjdk.java.net/code-tools/jmh/file/e810ce09937a/jmh-samples/src/main/java/org/openjdk/jmh/samples/JMHSample_29_StatesDAG.java
>
> Hmmm, I wrote this [code at the end of the message] and sometimes I got
> exception from my setup method, that shows that it was called twice. My
> ".registerReader()" and ".registerWriter()" checks, that they was called
> only once, and sometimes it is not the case and my invariant check
With @State(Scope.Thread), @Setup method would be called once by *each
thread* that has a reference to a state object. Is that what you are
seeing? If you have multiple threads calling e.g. writer(), then every
one will have its own thread-local instance of {Reader,Writer}State, and
try to register in your buf.
Anyhow, would be nice to see the MCVE example of the failure, because my
quick test does not fail:
@Fork(1)
@Warmup(iterations = 5, time = 5)
@Measurement(iterations = 10, time = 5)
@State(Scope.Group)
@Timeout(time = 5)
public class GroupThreadTimesTest {
@State(Scope.Group)
public static class GroupState {
static boolean visited;
@Setup
public synchronized void setup() {
if (visited) {
throw new IllegalStateException("Already visited!");
}
visited = true;
}
}
@State(Scope.Thread)
public static class ReaderState {
static final Set<Thread> threads =
Collections.newSetFromMap(new ConcurrentHashMap<Thread,
Boolean>());
@Setup
public void setup(GroupState gs) {
if (!threads.add(Thread.currentThread())) {
throw new IllegalStateException("Already visited by " +
Thread.currentThread());
}
}
}
@State(Scope.Thread)
public static class WriterState {
static final Set<Thread> threads =
Collections.newSetFromMap(new ConcurrentHashMap<Thread,
Boolean>());
@Setup
public void setup(GroupState gs) {
if (!threads.add(Thread.currentThread())) {
throw new IllegalStateException("Already visited by " +
Thread.currentThread());
}
}
}
@Benchmark
@Group("buf")
public void writer(WriterState s) throws InterruptedException {
// Write to buffer
}
@Benchmark
@Group("buf")
public void reader(ReaderState s) throws InterruptedException {
// Read from buffer
}
}
Thanks,
-Aleksey
More information about the jmh-dev
mailing list