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

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

🔥 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 路线」| 导读 —— 他山之石,可以攻玉 ,常来玩~


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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容