使用Java和JMH对无锁堆栈进行基准测试

使用Java和JMH对无锁堆栈进行基准测试,java,multithreading,concurrency,benchmarking,jmh,Java,Multithreading,Concurrency,Benchmarking,Jmh,在我的一门大学课程中,我被要求实现一个无锁堆栈实现,并对其执行基准测试,以了解它在线程计数和操作分布方面的伸缩性。我最近发现了JMH,我想我应该把它应用到家庭作业的基准测试部分。我只是不确定我是否尽可能优雅地实现了这一点 我的教授希望我们测量1、2、4、8、16和32个线程执行3种不同分布的操作所需的时间。我将其建模如下: package kylemart.multicore.assignment2; import org.openjdk.jmh.annotations.*; // Anno

在我的一门大学课程中,我被要求实现一个无锁堆栈实现,并对其执行基准测试,以了解它在线程计数和操作分布方面的伸缩性。我最近发现了JMH,我想我应该把它应用到家庭作业的基准测试部分。我只是不确定我是否尽可能优雅地实现了这一点

我的教授希望我们测量1、2、4、8、16和32个线程执行3种不同分布的操作所需的时间。我将其建模如下:

package kylemart.multicore.assignment2;

import org.openjdk.jmh.annotations.*;

// Annotations here... 
public class P1StackBenchmarks {

    @Benchmark
    public void runScenarioA(ScenarioA scenario) throws InterruptedException {
        runThreads(scenario.threads);
    }

    @Benchmark
    public void runScenarioB(ScenarioB scenario) throws InterruptedException {
        runThreads(scenario.threads);
    }

    @Benchmark
    public void runScenarioC(ScenarioC scenario) throws InterruptedException {
        runThreads(scenario.threads);
    }

    private void runThreads(Thread[] threads) throws InterruptedException {
        for (Thread thread : threads) {
            thread.start();
        }
        for (Thread thread : threads) {
            thread.join();
        }
    }

    @State(Scope.Benchmark)
    public static class BenchmarkParameters {

        @Param({"1", "2", "4", "8", "16", "32"})
        int threadCount;

        static final int iterations = 500_000;
    }

    @State(Scope.Thread)
    public static abstract class Scenario {

        Thread[] threads;
        PStack<Object> stack;
        Object object;

        @Setup(Level.Invocation)
        public void setup(BenchmarkParameters params) {
            threads = new Thread[params.threadCount];
            stack = new P1Stack<>();
            object = new Object();
            Runnable runnable = () -> {
                for (int iteration = 0; iteration < params.iterations; iteration++) {
                    operations();
                }
            };
            for (int index = 0; index < threads.length; index++) {
                threads[index] = new Thread(runnable);
            }
        }

        protected abstract void operations();
    }

    public static class ScenarioA extends Scenario {

        @Override
        protected void operations() {
            // stack.push(object);
            // ...
        }
    }

    public static class ScenarioB extends Scenario {

        @Override
        protected void operations() {
            // stack.push(object);
            // ...
        }
    }

    public static class ScenarioC extends Scenario {

        @Override
        protected void operations() {
            // stack.push(object);
            // ...
        }
    }
}
包kylemart.multicore.assignment2;
导入org.openjdk.jmh.annotations.*;
//这里的注释。。。
公共类基准{
@基准
public void runScenarioA(ScenarioA场景)引发InterruptedException{
运行线程(scenario.threads);
}
@基准
public void runScenarioB(ScenarioB场景)引发中断异常{
运行线程(scenario.threads);
}
@基准
public void runScenarioC(场景场景)抛出InterruptedException{
运行线程(scenario.threads);
}
私有void运行线程(线程[]线程)引发InterruptedException{
用于(线程:线程){
thread.start();
}
用于(线程:线程){
thread.join();
}
}
@国家(范围、基准)
公共静态类基准参数{
@参数({“1”、“2”、“4”、“8”、“16”、“32”})
int线程数;
静态最终整数迭代=500_000;
}
@状态(Scope.Thread)
公共静态抽象类场景{
线程[]线程;
PStack堆栈;
对象对象;
@设置(级别调用)
公共无效设置(基准参数参数){
线程=新线程[params.threadCount];
stack=新的P1Stack();
对象=新对象();
Runnable Runnable=()->{
for(int iteration=0;iteration
每个场景A、B和C都有一个
operations()
方法,该方法定义了一组堆栈操作,其特定频率为
pop()
push()
size()
调用。抽象场景类是这些特定场景的“模板”。假设注释是可继承的(这似乎是事实——不介意有人对此进行事实检查),我希望这三个具体场景类的实例的作用域是单个线程(即
@State(Scope.Thread)
),并具有其
设置()
方法在每次调用基准方法之前运行(即
@Setup(Level.invocation)
)。通过这样做,我能够在开始运行线程之前构建和设置每个场景的线程


这个实现有什么问题吗?JMH是否有其他设施使该问题更容易解决/实施?谢谢

如果您要求对代码进行审查,那么适当的站点是