【发布时间】:2021-12-14 03:24:41
【问题描述】:
如果 CPU 一次只实时执行一项任务,那么多线程与单处理器系统中的异步编程(在效率方面)有何不同?
假设我们必须从 1 数到 IntegerMax。在我的多核机器的以下程序中,两个线程的最终计数几乎是单线程计数的一半。如果我们在单核机器上运行它会怎样?有什么方法可以实现同样的结果吗?
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
【问题讨论】:
-
IDK 关于效率,但编写线程代码而不是执行异步代码的最初原因是为了可读性。每个线程都可以像我们在初学者时都学会编写的简单的单线程程序程序一样。当您有多个异步活动正在进行时,程序必须显式存储每个活动的状态,并且必须显式地从活动切换到活动。对于线程,每个活动的状态是隐式在其线程的局部变量中的,所有的调度都由“系统”为你处理。
标签: java multithreading asynchronous concurrency operating-system