栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程基础知识学习总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程基础知识学习总结

多线程基础知识学习总结
  • 线程的历史 —— 一部对CPU压榨的血泪史
  • 线程进程概念
    • 单核CPU设定多线程是否有意义?
    • 工作线程数是否设置的越大越好?

线程的历史 —— 一部对CPU压榨的血泪史

1、单线程人工切换(纸带机)
CPU利用效率低很多时间是等着人去换各种纸带
2、多进程批处理(多个任务批量执行)
但是如果其中一个任务等待的话也会导致其他任务跟着等待
3、多进程并行处理(把程序写在不同的内存位置上来回切换)
4、多线程(一个程序内部不同任务的来回切换)
5、纤程/协程(绿色线程,用户管理的【而不是OS管理的】线程)

线程进程概念


首先看上面这个计算机的组成,
程序:
可执行文件。
进程:
首先双击我们电脑的一个程序比如QQ.exe,它会经过操作系统并把当前程序信息加载到内存中,内存中就有一个正在运行的QQ.exe,我们也可以再次点击QQ.exe登录另外的账号,所以一个程序是可以在内存里面放很多份的,在内存里面的每一份都可以称为一个进程。
进程就是操作系统分配资源的基本单位。(静态概念)

线程:
依然如上图,我们之前说点击QQ.exe,双击时我们的程序会进入到内存中变成一个进程,真正开始执行的时候程序是以线程为单位来执行的,操作系统会找到我们的主线程扔给CPU执行,然后如果主线程开启了其他的线程,CPU会在这些线程中来回切换。
概念上:线程就是CPU调度执行的基本单位(动态概念:多个线程共享同一个进程里的所有资源)
线程切换(底层角度理解):

ALU:计算单元
Registers:寄存器组(用于存放数据)
PC寄存器(存储到底执行到哪条指令了)
cache:缓存
所以当T1线程要运行的时候把T1的数据和指令放在CPU中,然后CPU计算单元对他进行计算,计算好了该做输出做输出,该做其他操作做其他操作。
但是根据操作系统调度算法的话,T1线程执行到一半把当前的CPU时间片用完了那么就会将T1的指令和数据放在缓存中,然后切换将T2的指令和数据放在CPU中继续做计算。如果T2的执行时间到了,就将T2的指令和数据放缓存里,再从缓存里面读取T1的数据和指令(当然这中间需要操作系统的调度切换【线程上下文切换】)。

单核CPU设定多线程是否有意义?

有意义,比方说我的某一个在CPU执行的任务需要等待网络响应(等待的过程不消耗CPU资源),那么等待的这段时间如果设置了多线程的话,就可以切换到其他线程去执行任务,这样就可以充分利用CPU的资源。
CPU密集型:大量时间做计算。
CPU的IO密集型:大量时间在等待。

工作线程数是否设置的越大越好?

不是,这样导致CPU资源消耗在对线程的切换上面去了

public class Main {
    //===================================================
    private static double[] nums = new double[10_0000_000];
    private static Random r = new Random();
    private static DecimalFormat df = new DecimalFormat("0.00");

    static {
        for (int i = 0; i < nums.length; i++) {
            nums[i] = r.nextDouble();
        }
    }

    private static void m1() {
        long start = System.currentTimeMillis();

        double result = 0.0;
        for (int i = 0; i < nums.length; i++) {
            result += nums[i];
        }

        long end = System.currentTimeMillis();

        System.out.println("m1: " + (end - start) + " result = " + df.format(result));
    }

    //=======================================================
    static double result1 = 0.0, result2 = 0.0, result = 0.0;

    private static void m2() throws Exception {

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < nums.length / 2; i++) {
                result1 += nums[i];
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = nums.length / 2; i < nums.length; i++) {
                result2 += nums[i];
            }
        });

        long start = System.currentTimeMillis();
        t1.start();
        t2.start();
        t1.join();
        t2.join();

        result = result1 + result2;

        long end = System.currentTimeMillis();

        System.out.println("m2: " + (end - start) + " result = " + df.format(result));
    }

    //===================================================================

    private static void m3() throws Exception {

        final int threadCount = 10000;
        Thread[] threads = new Thread[threadCount];
        double[] results = new double[threadCount];
        final int segmentCount = nums.length / threadCount;
        CountDownLatch latch = new CountDownLatch(threadCount);

        for (int i = 0; i < threadCount; i++) {
            int m = i;

            threads[i] = new Thread(() -> {
                for (int j = m * segmentCount; j < (m + 1) * segmentCount && j < nums.length; j++) {
                    results[m] += nums[j];
                }
                latch.countDown();
            });

        }

        double resultM3 = 0.0;

        long start = System.currentTimeMillis();
        for (Thread t : threads) {
            t.start();
        }

        latch.await();
        for(int i=segmentCount*threadCount;i
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/318657.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号