【问题标题】:Synchronized multi-threading vs single thread同步多线程 vs 单线程
【发布时间】:2016-06-07 20:08:05
【问题描述】:

我正在尝试通过多线程和单线程计算 100 个数字。由于 synchronized 关键字一次只允许一个线程(有点像单个线程),那么如果忽略创建和同步线程的耗时影响,下面这两个方法应该具有大致相同的运行时间?

使用同步的多线程:

public synchronized static void increment() {
    sum++;
}

public static void main(String[] args) {
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 50; i++) {
                increment();
            }
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 50; i++) {
                increment();
            }
        }
    });
    t1.start();;
    t2.start();
    try {
        t1.join();
        t2.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(sum);

单线程:

public static void main(String[] args) {
    for (int i = 0; i < 100; i++) {
        sum++
    }

    System.out.println(sum);
}

【问题讨论】:

  • 第二种方法中的t1是什么?你的意思是t3
  • 是的。我编辑了它。 @AndyTurner
  • "使用同步的单线程:" 实际上,这是多线程的。你有主线程和t3。而且你没有使用synchronized
  • 我的错。请看我的编辑。 @AndyTurner
  • 对于更大的计数和单线程情况,JIT 可以完全消除循环并打印出计数。对于多线程的情况,这是做不到的,所以多线程的代码会慢很多。

标签: java multithreading semaphore synchronized


【解决方案1】:

Java 确实擅长多线程,但创建和同步线程会产生大量开销,因此,如果对于像数到 100 这样的简单问题,您实际上看到运行时间增加了,请不要感到惊讶。

【讨论】:

  • 如果忽略线程创建和同步耗时的影响,它们的运行时间应该大致相同吧? @Scott Twombly
  • 当然,但我认为这样做是不明智的。您无法将 jvm 与 java 分开。如果您只想计算一个数字增加的次数,当然它们在两种情况下都是相同的,但这是一个几乎毫无意义的指标。在您的多线程示例中,发生了更多“事情”并且在后台调用了方法,忽略它们让我想知道,首先比较这些事情有什么意义? @SHE
  • @SHE,您错过了 Thomas Kläger 的观点(请参阅上面他对您的问题的评论)。一个好的编译器可以识别出由单线程示例计算的sum 不依赖于任何变量、任何函数调用、任何输入。这只是一个常数。它是 4950,而且总是 4950。一个好的编译器可以用 sum = 4950; 替换整个循环,这不会改变程序的输出,但它会使其运行得更快。但是,没有编译器可以为多线程版本做到这一点。太复杂了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 2012-03-06
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
相关资源
最近更新 更多