当前位置:   article > 正文

多核、多线程、并发与并行_多核多线程

多核多线程

一、概念

  • 进程与线程
    进程是操作系统进行资源分配管理和调度的单元,比如我们打开QQ,运行的QQ就是一个进程。
    线程是进程的一个子集,线程是CPU进行调度和执行的单元。
    一个进程可以包含一个线程(单线程的进程),也可以包含多个线程(多线程的进程)。
  • 多核与多线程
    在单核时代,也可以实现多线程,同一时间内,各个(同一或者不同)线程争夺CPU时间片。
    在多核时代,各个进程及其线程可以在不同CPU内核上执行。多核为多线程并行执行提供了可能。
  • 并发、并行与串行
    串行:各个线程排队等待CPU的执行。
    并发:指的是不同线程同时争夺一个CPU内核的时间片,这种状态就是并发。
    在这里插入图片描述
    并行:不同线程在不同CPU内核上同时执行,彼此相互不影响。
    在这里插入图片描述

二、效率与时间

我们通常说并发能够提升执行效率,觉得并发就跟提升效率有关。
现在假设有一种情况,一个多线程的进程,在被分配在固定的CPU内核上执行,各个线程虽然在并发,但是CPU一会执行这个线程,一会儿执行那个线程,不断切换,这个跟CPU先执行完A线程的任务,再执行完B线程的任务,接着C线程的任务…并没有什么时间效率上的提升,更有甚者,CPU在不断切换线程时,也需要不断切换线程上下文,切换上下文会带来时间和资源开销,与其这样并发,还不如串行呢?
所以,这里有个理解误区,提升效率不等于缩短执行时间。
假使打开QQ,我们一边时而回复聊天,时而逛空间,如果,采用串行的方式,我们就得等聊天完成后,才能正常逛空间;而如果采用多线程的方式,CPU不断切换线程执行,宏观上我们就会觉得聊天和逛空间完全可以同时进行。这就是提升了效率。
另一点理解误区,并发能缩短总执行时间。
一个多线程的进程运行在多核CPU上,它到底是并行还是并发,这个我不知道,因为CPU调度一会儿把线程分配在这个CPU内核上,一会儿把CPU分配在那个CPU内核上,各个线程可能在同一CPU内核,也可能在不同CPU内核。当在不同的CPU内核执行时,这两个线程就是并行;当两个CPU内核同时争夺同一个CPU内核的时间片时,这两个线程就是并发。
而并行才能缩短总的执行时间。

三、多线程的进程不一定会使用多核并行处理

验证如下:
本机电脑4核8G。
如下案例,开启4个线程每个线程依次打印100万次。

package org.example.demo5;

public class ThreadTest {

    private static final int num = 1000 * 1000;

    public static void main(String[] args) throws InterruptedException {
        //因为Visual VM找到java进程需要时间,所以这里让主线程先睡一会儿,
        //等待Visual VM找到进程再开始启动各子进程打印
        Thread.sleep(50000); 

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }

        },"线程1").start();

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }

        },"线程2").start();

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }
        },"线程3").start();

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }
        },"线程4").start();

    }
}
  • 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

通过使用Visual VM查看线程状态,可知各个线程是在同一个CPU上并发执行的。
图片
修改执行次数,改成2000万次

package org.example.demo5;

public class ThreadTest {

    private static final int num = 20000 * 1000;

    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(50000);

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }

        },"线程1").start();

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }

        },"线程2").start();

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }
        },"线程3").start();

        new Thread(()->{
            for (int i = 0; i < num; i++) {
                System.out.println(i);
            }
        },"线程4").start();

    }
}
  • 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

通过下图可知,4个线程同时存在并发核并行的情况。
在这里插入图片描述

根据以上案例可知:
一个多线程的进程在多核处理器上,可能是以并发的方式运行,也可能是以并发+并行的方式运行。

参考:

https://www.cnblogs.com/jiading/articles/12454398.html
https://blog.csdn.net/qq_33290787/article/details/51790605
Visual VM工具的使用
https://www.cnblogs.com/xifengxiaoma/p/9402497.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/151304
推荐阅读
相关标签
  

闽ICP备14008679号