You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单核系统中Multithreaded与Asynchronous编程的效率差异及实例疑问

问题解答

1. 示例累加程序在单核机器上的运行结果

你提供的是典型的CPU密集型任务,全程没有任何IO等待、锁等待的空耗,CPU全程处于满负载运算状态。放到单核设备上运行时,双线程版本的耗时会高于单线程版本,不会再出现多核下耗时减半的效果:

  • 单线程版本耗时和多核下基本一致,没有额外开销
  • 双线程版本需要额外支付操作系统的线程调度、上下文切换成本,耗时通常会比单线程慢10%~30%

2. 单处理器环境下多线程与异步编程的效率差异

两者的效率差异仅在IO密集型场景下体现,CPU密集型场景下两者都不可能突破单核算力上限,不会比纯单线程串行执行效率更高:

  • 多线程处理IO密集任务时,线程发起IO请求后会被操作系统挂起,IO完成后再唤醒,整个过程存在线程上下文切换开销。如果并发IO任务量很大,大量线程的切换开销会占用大量CPU资源,反而降低整体效率
  • 异步编程基于「非阻塞IO+单线程事件循环」实现,发起IO请求后不会挂起线程,会直接继续处理其他待执行任务,等IO完成通知到达后再回头处理后续逻辑,全程没有线程切换开销,单核IO密集场景下的效率远高于多线程方案

3. 单核环境下能否实现同等的效率提升

  • 对于你给出的CPU密集型累加任务:不可能实现。这类任务的总运算量固定,单核算力上限固定,没有多余的核心可以用来并行运算,无论用什么编程模型都不可能达到多核双线程的效率
  • 对于IO密集型任务:可以实现。异步编程可以把CPU原本等待IO的空闲时间完全利用起来,没有多线程的额外开销,单核下的处理效率甚至可以超过多核多线程方案

附测试代码

class Demonstration {
    public static void main( String args[] ) throws InterruptedException {
        SumUpExample.runTest();
    }
}

class SumUpExample {

    long startRange;
    long endRange;
    long counter = 0;
    static long MAX_NUM = Integer.MAX_VALUE;

    public SumUpExample(long startRange, long endRange) {
        this.startRange = startRange;
        this.endRange = endRange;
    }

    public void add() {

        for (long i = startRange; i <= endRange; i++) {
            counter += i;
        }
    }

    static public void twoThreads() throws InterruptedException {

        long start = System.currentTimeMillis();
        SumUpExample s1 = new SumUpExample(1, MAX_NUM / 2);
        SumUpExample s2 = new SumUpExample(1 + (MAX_NUM / 2), MAX_NUM);

        Thread t1 = new Thread(() -> {
            s1.add();
        });

        Thread t2 = new Thread(() -> {
            s2.add();
        });

        t1.start();
        t2.start();
        
        t1.join();
        t2.join();

        long finalCount = s1.counter + s2.counter;
        long end = System.currentTimeMillis();
        System.out.println("Two threads final count = " + finalCount + " took " + (end - start));
    }

    static public void oneThread() {

        long start = System.currentTimeMillis();
        SumUpExample s = new SumUpExample(1, MAX_NUM );
        s.add();
        long end = System.currentTimeMillis();
        System.out.println("Single thread final count = " + s.counter + " took " + (end - start));
    }


    public static void runTest() throws InterruptedException {

        oneThread();
        twoThreads();

    }
}

多核设备运行输出

Single thread final count = 2305843008139952128 took 1003
Two threads final count = 2305843008139952128 took 540

内容的提问来源于stack exchange,提问作者Shikhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:24:03