Java 如何仅使用一个线程检查多线程的性能?

Java 如何仅使用一个线程检查多线程的性能?,java,multithreading,context-switching,Java,Multithreading,Context Switching,我正在学习Java多线程,并试图检查多线程的性能。我试图检查多线程是否比单线程更好。 所以,我写了一个求和到极限的代码。 当限制变得更大时,它就像我预期的那样工作(多线程比单线程快),但当限制很小时(如10000L),它就没有工作。 这是因为上下文切换吗?下面的代码是否适合检查多线程的性能 public class MultiThreadingSum { long count = 0; static long limit = 1000000000L; static vo

我正在学习Java多线程,并试图检查多线程的性能。我试图检查多线程是否比单线程更好。 所以,我写了一个求和到极限的代码。 当限制变得更大时,它就像我预期的那样工作(多线程比单线程快),但当限制很小时(如10000L),它就没有工作。 这是因为上下文切换吗?下面的代码是否适合检查多线程的性能

public class MultiThreadingSum {
    long count = 0;
    static long limit = 1000000000L;

    static void compareMultipleThreadToSingleThread(int threadCnt) {
        Runnable r = () -> {
            MultiThreadingSum mts = new MultiThreadingSum();
            long startTime = System.nanoTime();
            while(++mts.count<=limit);
            long endTime = System.nanoTime();
            long estimatedTime = endTime - startTime;
            double seconds = estimatedTime / 1000000000.0;

            System.out.println(Thread.currentThread().getName()+", elapsed time : "+seconds);
        };

        for(int i=0; i<threadCnt; i++) {
            new Thread(r, "multiThread"+i).start();
        }

        Runnable r2 = () -> {
            MultiThreadingSum mts = new MultiThreadingSum();
            long startTime = System.nanoTime();
            while(++mts.count<=limit*threadCnt);
            long endTime = System.nanoTime();
            long estimatedTime = endTime - startTime;
            double seconds = estimatedTime / 1000000000.0;

            System.out.println(Thread.currentThread().getName()+", elapsed time : "+seconds);
        };

        new Thread(r2, "singleThread").start();
    }

    public static void main(String[] args) {
        compareMultipleThreadToSingleThread(3);
    }
}
公共类多线程sum{
长计数=0;
静态长限=1000000000L;
静态无效比较MultipleThreadToSingleThread(int-threadCnt){
可运行r=()->{
multi-threadingsum mts=新的multi-threadingsum();
long startTime=System.nanoTime();

虽然(++mts.count这不是一个好例子。多线程和单线程解决方案同时在同一个计数器上运行。因此,实际上您运行一个具有四个线程的多线程进程。您需要运行一个解决方案,直到线程完成并关闭,然后运行另一个。最简单的解决方案是将单线程进程作为一个线程运行在main方法中进行简单循环,并在循环完成后运行多线程解决方案。此外,我将有两个单独的计数器,或者,您可以在单线程循环完成后为计数器指定零。在运行单线程实验之前,您的代码不会等待三线程实验完成。因此,您可能正在污染您的代码你的结果

你的代码似乎不必要的复杂。我们不能分别运行两个单独的实验,一个有3个线程,一个有1个线程,来重用代码吗

在现代Java中,我们很少需要处理
线程
类,而是使用添加到Java5中的executor服务框架

把这些放在一起,也许你的实验应该看起来更像下面

警告:这只是一个非常粗糙的切割,我还没有想清楚,我的咖啡已经喝完了。所以仔细地修改这段代码。也许我可以在一两天内修改这段代码

package work.basil.threading;
导入java.time.Duration;
导入java.time.Instant;
导入java.util.List;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
导入java.util.concurrent.AtomicInteger;
公共类循环
{
公共静态void main(字符串[]args)
{
Loopy app=新的Loopy();
ListinputThreadsLimit=List.of(1,3,(Runtime.getRuntime().availableProcessor()-1));
for(整数个线程:inputThreadsLimit)
{
System.out.println(“--------------线程计数实验:“+numberOfThreads+”);
Duration Duration=app.demo(numberOfThreads);//在此等待实验运行完成。
System.out.println(numberOfThreads+“=”+duration+”总计,每个:“+duration.divided by(numberOfThreads));
}
}
//成员字段
最终私有AtomicInteger计数=新的AtomicInteger(0);
私有持续时间演示(最终int numberOfThreads)
{
ExecutorService ExecutorService=Executors.newFixedThreadPool(线程数);
长启动=System.nanoTime();
for(int i=0;i
我认为您正在比较完成一项任务所需的时间
r
r*threadCnt
的时间。您需要测量从第一次
r
开始到最后一次
r
之后的时间。使用
join()
method或
CompletableFuture
类等待所有线程完成。测量时不要在线程中使用
System.out
语句。出于这些原因@onkarruikar我甚至不知道这一点。。非常感谢!非常感谢!但是有一个问题,我的代码线程不安全吗?因为它声明了新的多线程sum()在arrow函数中,@zz9z9 Lambda语法与线程安全无关。但是,该语法正在实例化,所以您是对的,count var在不同的实例中,因此线程安全,我将其误读为静态。我明天将更正我的答案。我认为每个线程都有自己的MultiThreadingSum实例,并将其作为一个实例进行计数变量,因此每个线程都无法访问其他线程的MultiThreadingSum实例和count变量。这是错误的吗?不,我错了,你关于
count
线程安全的看法是正确的。我删除了那些批评。无论如何,感谢你的大力帮助!我会尝试你提到的内容。非常感谢!