Java多线程为什么比单线程快?

版权声明:本文为奥维原创文章,未经允许不得转载.

多线程似乎一直给我们这样的印象就是多线程比单线程快,其实这是一个伪命题.事无绝对,多线程有时候确实比单线程快,但也有很多时候没有单线程那么快. 首先简单区分一下并发性(concurrency)和并行性(parallel).并行是说同一时刻有多条命令在多个处理器上同时执行.并发是说同一时刻只有一条指令执行,只不过进程(线程)指令在CPU中快速轮换,速度极快,给人看起来就是”同时运行”的印象,实际上同一时刻只有一条指令进行. 但实际上如果我们在一个应用程序中使用了多线程,线程之间的轮换以及上下文切换是需要花费很多时间的,这样的话当我们执行类似循环之类的操作的时候,是不是就意味着单线程一定会比多线程快呢(因为单线程的执行没有线程切换的时间消耗),看下面一段代码(出自<<Java并发编程的艺术>>)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class ConcurrencyTest {
private static final long count = 1000000000;

public static void main(String[] args) {
try {
concurrency();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
serial();
}

private static void concurrency() throws InterruptedException {
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable() {

@Override
public void run() {
int a = 0;
for (long i = 0; i < count; i++)
{
a += 5;
}
}
});
thread.start();
int b = 0;
for (long i = 0; i < count; i++)
{
b--;
}
thread.join();
long time = System.currentTimeMillis() - start;
System.out.println("concurrency : " + time + "ms,b=" + b);
}

private static void serial() {
long start = System.currentTimeMillis();
int a = 0;
for (long i = 0; i < count; i++)
{
a += 5;
}
int b = 0;
for (long i = 0; i < count; i++)
{
b--;
}
long time = System.currentTimeMillis() - start;
System.out.println("concurrency : " + time + "ms,b=" + b);
}

}
这段代码的运行结果是当count值比较小的时候单线程的运行速度比多线程要快,当count的值比较大的时候多线程的速度大概会是单线程的两倍为什么会这样呢,理论上来说执行上述这种代码操作单线程不需要上下文切换应该肯定比多线程要快才对呀. 其实是因为我们异想天开了,CPU的资源又不是全部都给你这个Java程序使用的,别的程序也要占用CPU资源啊.比如说当我们这个程序还没有运行的时候其实可能操作系统中已经有50个线程在运行了,那么当我们这个程序运行的时候,单线程就会占用CPU51分之1的时间(假设每个线程占用时间相等),多线程就会占用CPU52分之2的时间,你说哪个会运行的更快呢.当然当数量比较少的时候上下文之间的轮换会占用相对较多的时间所以这个时候虽然多线程占用CPU52分之2的时间,但是切换也需要很多的时间所以就比单线程要慢.
月月说要给我打赏,就还是放了二维码,😝