美文网首页
「Java 路线」| 并发编程的基础概念

「Java 路线」| 并发编程的基础概念

作者: 彭旭锐 | 来源:发表于2021-01-02 19:41 被阅读0次

    点赞关注,不再迷路,你的支持对我意义重大!

    🔥 Hi,我是丑丑。本文 「Java 路线」| 导读 —— 他山之石,可以攻玉 已收录,这里有 Android 进阶成长路线笔记 & 博客,欢迎跟着彭丑丑一起成长。(联系方式在 GitHub)


    前言

    • 并发编程 是面试的重点,同时也是 Java 开发从入门到精通遇到的第一个坎;
    • 这篇文章是 Java 并发系列的第一篇文章,为了帮助小白们渐进深入,我们先来介绍并发编程中的基础概念。如果能帮上忙,请务必点赞加关注,这真的对我非常重要。

    目录


    1. 基本概念

    1.1 进程与线程

    • 1、进程是操作系统进行资源分配的最小单位,而线程是 CPU 调度的最小单位;
    • 2、一个进程里可以有多个线程,线程必须依赖于进程存在;
    • 3、不同进程之间地址空间和资源是独立的,同一进程中的线程共享进程的地址空间和资源,但不共享线程工作空间。

    1.2 CPU 与处理器

    • 1、根据摩尔定律,集成电路上可以容纳的晶体管数目在大约每经过 24 个月便会增加一倍。但是当晶体管大小降低到一定程度会出现 「量子隧穿」,无法继续提高晶体管的密度。因此,发展出了 单芯片多处理器技术 ,即多个处理器集成到同一个 CPU 芯片上,各个处理器处理不同的线程。所谓四核 CPU 值得就是一颗 CPU 拥有四个处理器。

    • 2、一般情况下,一个处理器只能处理一个线程,Intel 研发的 「超线程」 技术可以使得一个处理器处理两个线程,让单个处理器就能使用多线程「并行」操作。

    1.3 CPU 时间片轮转机制

    时间片轮转机制(又称 Round-Robin,RR 调度),是用于分时系统的线程调度机制,要点如下:

    • 1、调度程序根据线程优先级抢占线程的 CPU 时间片;
    • 2、线程结束、阻塞或者让出时间片时,CPU 会切换执行线程(让出时间片后依然有可能重新获得);
    • 3、时间片过长会降低响应性,时间片过短会增加过多线程切换,降低 CPU 吞吐量。

    易混淆: 线程的时间片分配是抢占式的,而线程间的工作是协作式的。

    1.4 并行 & 并发

    • 并行(Parallel): 指多个 CPU 核心分别执行不同线程,两个线程之间不抢占 CPU 资源,可以同时运行;

    • 并发(Concurrent): 指一个 CPU 核心交替执行不同线程,从单位时间的宏观角度看,多个线程开起来是同时运行的。(讨论并发一定要约定单位时间)

    1.5 并发编程注意事项

    • 线程安全

    • 线程死锁

    • 线程过多

    OS限制:一个进程Linus最大线程1000 window最大线程2000
    线程:栈空间(缺省1M)、文件描述符/句柄1024

    • 线程饥饿

    Editting...


    2. Java 中的线程

    2.1 执行 main() 方法,会启动几个线程?

    总所周知,main() 方法是 Java 程序的入口,运行在主线程(线程名:main)。事实上,除了主线程外,虚拟机同时还启动了其他子线程。我们可以通过以下代码打印运行的线程:

    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    ThreadInfo[] threadInfos =  threadMXBean.dumpAllThreads(false, false);
    for(ThreadInfo threadInfo:threadInfos) {
        System.out.println("["+threadInfo.getThreadId()+"]"+" " +threadInfo.getThreadName());
    }
    

    输出如下:

    线程 作用
    [1] main 主线程
    [2] Reference Handler 清除 Reference
    [3] Finalizer 调用 finalize() 方法
    [4] Signal Dispatcher 分发处理发送给 JVM 信号
    [5] Attach Listener 内存 dump,线程 dump,类信息统计,获取系统属性等
    [6] Monitor Ctrl-Break 监控 Ctrl-Break 中断信号

    2.2 启动线程的方式

    提示: 启动线程的方式有人认为有两种,有人认为有三种。建议不必纠结于结论,关注是否自圆其说即可。

    根据 JDK 官方在java.lang.Thread.java 中的注释,存在 两种启动线程 的方式:

    There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread.
    ...
    The other way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as an argument when creating Thread, and started.

    • 1、继承 Thread 类,重写 run(),随后调用 Thread#start();
    • 2、实现 Runnable 接口,重写 run(),并关联 Thread,随后调用 Thread#start()

    有的说法会将java.util.concurrent.Callable也列为一种启动方式,其实 Callable 只是 java.util.concurrent.FutureTask的任务接口,而 FutureTask 本身就是 Runnable 的子类,所以「两种方式」的说法更有说服力。

    FutureTask<V> ->RunnableFuture<V> -> Runnable
    

    Thread 和 Runnable 的区别

    Thread 是 Java 线程的抽象,Runnable 是对任务的抽象,与线程没有直接关系。Thread 可以接受任意一个 Runnable 的实例并执行。

    start() 和 run() 的区别

    start() 是启动一个线程,让一个线程进入「就绪状态」等待分配 CPU 时间片,分到时间片后执行 run() 方法,start() 方法重复执行会抛出异常;而 run() 方法是承载业务逻辑的地方,本质上是一个普通的实例方法,可以重复执行。

    2.3 线程终止的方式

    • 1、自然终止

    Thread#run()执行结束,或者执行过程抛出了未捕获的异常,则线程 自然终止。

    • 2、stop()

    线程停止、暂停和恢复分别对应suspend () & resume() & stop(),需要注意的是,这些 API 都是 过时的

    • suspend():暂停线程,当前线程不会释放锁资源,而是占有锁进入睡眠状态,容易引发死锁;

    • stop():停止线程,没有给予线程释放资源的时机。

    • 3、中断

    中断本质上不属于终止线程的方式,但是往往 中断会给予线程终止的时机。例如在sleep() 、wait()等方法上阻塞的线程,就可以利用中断来退出等待,进而判断是否应该终止线程的业务逻辑。关于中断的具体介绍,见「Java 路线」| 线程协作机制

    提示: 可以响应中断的方法往往声明throws InterruptedException


    3. 线程优先级

    Edigging...


    4. 守护线程

    4.1 定义

    守护(Daemon)线程是一种支持型线程,当虚拟机中所有非守护线程都终止时,虚拟机就会退出,不理会守护线程是否终止。

    例如 第 2.1 节 中提到的 Reference Handler 线程和 Finalizer 线程就是守护线程。通过Thead#setDaemon(true)可以设置守护线程,

    4.2 finally{} 块一定会执行吗?

    一般来说,try-catch-finally 代码块中 finally 块是一定会执行的,除了以下特殊情况,finally{} 块不一定会执行

    • 1、finally{} 执行之前调用System.exit(0):虚拟机都推出了,finally{} 块当然也没机会执行了;
    • 2、守护线程:当虚拟机中所有非守护线程都终止时,虚拟机就会退出,这个时候守护线程中的 finally{} 块也有可能不会执行。

    掌握了并发编程的基本概念,下面我们就可以愉快地深入交流了,所有精彩内容尽在: 「Java 路线」| 导读 —— 他山之石,可以攻玉 ,常来玩~


    创作不易,你的「三连」是丑丑最大的动力,我们下次见!

    相关文章

      网友评论

          本文标题:「Java 路线」| 并发编程的基础概念

          本文链接:https://www.haomeiwen.com/subject/dwikoktx.html