java - 为什么使用两个线程作为计数器会降低 Java 的性能?

标签 java python multithreading

python中,使用两个线程来实现简单的计数器程序(如下所示)比使用单个线程的程序要慢。原因在于全局解释器锁背后的机制。

我在 java 中测试了相同的内容以查看性能。在这里,我再次发现单个线程在时间尺度上优于双线程。为什么会这样?

这是代码:

public class ThreadTiming {

    static void threadMessage(String message) {
        String threadName =
            Thread.currentThread().getName();
        System.out.format("%s: %s%n",
                          threadName,
                          message);
    }

    private static class Counter implements Runnable {

        private int count=500000000;
        @Override
        public void run() {

            while(count>0) {
                count--;
            }
            threadMessage("done processing");
        }
    }

    public static void main(String[] args) throws InterruptedException{
        Thread t1 = new Thread(new Counter());
        Thread t2 = new Thread(new Counter());

        long startTime=System.currentTimeMillis();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        long endTime=System.currentTimeMillis();
        System.out.println("Time taken by two threads "+ (endTime-startTime)/1000.0);

        startTime=System.currentTimeMillis();
        Calculate(2*500000000);
        endTime=System.currentTimeMillis();
        System.out.println("Time taken by single thread "+ (endTime-startTime)/1000.0);
    }

    public static void Calculate(int x){
        while (x>0){
            x--;
        }
        threadMessage("Done processing");
    }
}

输出:

Thread-1: done processing
Thread-2: done processing
Time taken by two threads 0.052
main: Done processing
Time taken by single thread 0.0010

最佳答案

非常简单。单线程版本使用局部变量,热点没有问题,因为它永远不会离开作用域,因此整个函数被简化为一个 nop。

另一方面,证明实例变量永远不会离开作用域(你好反射!)要困难得多,而且显然热点不能在这里,因此循环不会被删除。

总的来说,基准测试很困难(我计算了至少三个可能导致“错误”结果的其他错误)并且需要大量知识。您最好使用 jmh(java 测量工具),它可以处理大多数事情.

关于java - 为什么使用两个线程作为计数器会降低 Java 的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24743804/

相关文章:

iphone - 在后台保存 NSManagedObjectContext

java - 成员变量的hashCode()值不同

javascript - 文件中的行号与 HTML 表单的文本区域字段中的行号之间的对应关系

python - 无法在 opencv3.2(ubuntu,python3)中读取 mp4

python - 主线程退出后如何让守护线程保持事件状态?

c++ - 我在哪里可以找到 C++0x 同步原语的良好、可靠的文档?

java - 从 Java 在 Mac 中启动外部安装程序应用程序

java - 检查您要连接的端口是否正在使用

java - Cordova 和 startResolutionForResult VS。开始 Activity 返回结果

python - 将类转换为 Python 列表