Skip to content

Commit 34af26b

Browse files
update
1 parent affcc23 commit 34af26b

13 files changed

Lines changed: 41 additions & 56 deletions

代码质量/Refactoring.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
[toc]
22

3-
4-
5-
6-
73
# 3 - 坏代码的味道
84

95
## 3.1 Duplicated Code 重复的代码

并发编程/0.0 线程的基本概念.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ interrupt 的本意是打断、中断的意思,此方法仅仅是给线程加
226226
}
227227
```
228228

229-
除了`isInterrupted()` 方法外 `Thread.interrupted()`也有一样的功能,而且调用后会**重置 interrupt 的状态**。可以下次再次使用此线程。
229+
`Thread.interrupted()`且调用后会**重置 interrupt 的状态**。可以下次再次使用此线程。
230+
230231
```java
231232
// 在判断后将 interrupt 重置
232233
if (Thread.interrupted()) {
@@ -238,7 +239,7 @@ if (Thread.interrupted()) {
238239

239240
# InterruptedException
240241

241-
当阻塞方法收到中断请求(`interrupt()`调用的时候)的时候就会抛出InterruptedException异常。
242+
==当阻塞方法收到中断请求(`interrupt()`调用的时候)的时候就会抛出InterruptedException异常。==
242243

243244
例如:在当前线程 sleep 的这一秒过程中调用 `interrupt()`方法,就会立即停止 sleep 并抛出异常。**InterruptedException 被触发后会和 `Thread.interrupted() ` 一样重置 interrupt 的状态 **
244245

@@ -294,19 +295,21 @@ wait 并不是线程的方法,他是 Object 方法,相当于控制的是 mon
294295

295296
## Thread#join()
296297

297-
相当于不需要 synchronized 的 wait 方法
298+
在线程中调用另一个线程的 join() 方法,会将当前线程挂起,而不是忙等待,直到目标线程结束
298299

299-
## Thread.yield()
300+
对于以下代码,虽然 b 线程先启动,但是因为在 b 线程中调用了 a 线程的 join() 方法,b 线程会等待 a 线程结束才继续执行,因此最后能够保证 a 线程的输出先于 b 线程的输出。
300301

301-
做出**一下**让步,让步给同优先级的线程。
302302

303303

304+
## Thread.yield()
305+
306+
将自己的执行权限做**一下**让步,让步给同优先级的线程,当时谁能抢到就不管了,也有可能还是本线程抢到了执行权限。
304307

305308

306309

307310
# 线程造成的内存泄漏
308311

309312
JVM 不会回收正在运行中的线程。
310313

311-
Static
314+
312315

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
待续

并发编程/5.0 拓展:进程和线程的区别.md

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,7 @@
22

33
# 面试必问——线程与进程的区别
44

5-
6-
7-
*[作者:郝你个建强](https://www.huaweicloud.com/articles/d90c9bf248c8f1731946d65786c95379.html#)* 时间: 2021-02-05 09:59:01
8-
9-
[标签:](https://www.huaweicloud.com/articles/topic-A-1.html)[面试](https://www.huaweicloud.com/articles/topic_1573c74e227f14ded2daa71bb049ecda.html)[多线程](https://www.huaweicloud.com/articles/topic_c9daf4ad6b1b7a1a3e1f2eb57d4d2fc7.html)[操作系统](https://www.huaweicloud.com/articles/topic_30d23ef4f49e85f37f54786ff984032c.html)[线程和进程](https://www.huaweicloud.com/articles/topic_12721f73571f39bf8e1f85317cb5d870.html)
10-
11-
```
12-
【摘要】总结了其他文章,给自己提供一个方便的复习途径 进程: 进程是程序的一次执行过程,是程序在执行过程中的分配和管理资源的基本单位,每个进程都有自己的地址空间,线程至少有 5 种状态:初始态、执行态、等待态、就绪态、终止态。 线程: 线程是CPU调度和分派的基本单位,它可以和同一进程下的其他线程共享全部资源 联系: 线程是进程中的一部分,一个进程可以有多个线程,但线程只能存在于一个进程...
13-
```
14-
15-
[[828企业上云\]注册领8280元礼包 1核2G服务器69元秒杀 **优惠**](https://activity.huaweicloud.com/828_promotion/index.html?organic_arc)
16-
17-
[[免费课程\]Python编程学习路径 **上新**](https://education.huaweicloud.com/programs/2708d678-5dbb-4be2-afc4-88ae69f0dca3/about?isAuth=0&amp?organic)
18-
19-
[[免费套餐\]1核2G 2核4G云服务器免费 云数据库0元试用 **热销**](https://activity.huaweicloud.com/free_test/index.html?organic_arc)
20-
21-
[[开发利器\]开发者专享优惠,解决研发效率、集成难题 **公告**](https://activity.huaweicloud.com/Developer_0820.html?organic_arc)
22-
23-
总结了其他文章,给自己提供一个方便的复习途径
5+
> 进程: 进程是程序的一次执行过程,是程序在执行过程中的分配和管理资源的基本单位,每个进程都有自己的地址空间,线程至少有 5 种状态:初始态、执行态、等待态、就绪态、终止态。 线程: 线程是CPU调度和分派的基本单位,它可以和同一进程下的其他线程共享全部资源 联系: 线程是进程中的一部分,一个进程可以有多个线程,但线程只能存在于一个进程...
246
257
## 进程:
268

并发编程/A.锁/1.0 Synchronized、volatile、ReentrantLock.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ volatile 在 java 中有两条语意:
109109

110110
## 可见性
111111

112-
vloatile 实现的原理是基于硬件实现的:当变量在线程 A 的工作内存发生改变的时候,会立即回写主存,此时其他线程会嗅探到总线中数据的变化,从而将其他线程工作内存中的变量值标记为无效状态,从而达到==写操作先发生于读操作==,保证了变量值的可见性。
112+
vloatile 实现的原理是基于硬件实现的:当变量在线程 A 的工作内存发生改变的时候,会立即回写主存,此时其他线程会嗅探到总线中数据的变化,从而将其他线程工作内存中的变量值标记为==无效状态==,从而达到==写操作先发生于读操作==,保证了变量值的可见性。
113113

114114
==但是 volatile 并不能保证修饰变量的原子性==:例如以下的程序使用 vlatile 关键字修饰了 race ,按照我们的期望一共20个线程每个线程累加一万次,结果应该等于 20w,但是运行的结果只会比 20W 小上不少。
115115

并发编程/A.锁/2.0 CAS基础.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
## 悲观锁
1313

14-
总是假设最坏的情况,每次读取数据的时候都默认其他线程会更改数据,因此需要进行加锁操作,当其他线程想要访问数据时,都需要阻塞挂起。悲观锁的实现:
14+
==总是假设最坏的情况,每次读取数据的时候都默认其他线程会更改数据==,因此需要进行加锁操作,当其他线程想要访问数据时,都需要阻塞挂起。悲观锁的实现:
1515

1616
* 传统的关系型数据库使用这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁;
1717
* Java 里面的同步`synchronized`关键字的实现。
1818

1919
## 乐观锁
2020

21-
乐观锁,其实就是一种思想,总是认为不会产生并发问题,每次读取数据的时候都认为其他线程不会修改数据,所以不上锁,但是在更新的时候会判断一下在此期间别的线程有没有修改过数据,乐观锁适用于读操作多的场景,这样可以提高程序的吞吐量。实现方式:
21+
乐观锁,其实就是一种思想,==总是认为不会产生并发问题,每次读取数据的时候都认为其他线程不会修改数据,所以不上锁,但是在更新的时候会判断一下在此期间别的线程有没有修改过数据,==乐观锁适用于读操作多的场景,这样可以提高程序的吞吐量。实现方式:
2222

2323
* CAS 实现:Java 中 java.util.concurrent.atomic 包下面的原子变量使用了乐观锁的一种 CAS 实现方式,CAS 分析看下节。
2424
* 版本号控制:一般是在数据表中加上一个数据版本号 version 字段,表示数据被修改的次数,当数据被修改时,version 值会加一。当线程 A 要更新数据值时,在读取数据的同时也会读取 version 值,在提交更新时,若刚才读取到的 version 值为当前数据库中的 version 值相等时才更新,否则重试更新操作,直到更新成功
@@ -31,13 +31,13 @@
3131

3232
在 jdk1.5 之前都是使用`synchronized`关键字保证同步,`synchronized`保证了无论哪个线程持有共享变量的锁,都会采用独占的方式来访问这些变量, 导致会存在这些问题:
3333

34-
* 在多线程竞争下,加锁、释放锁会导致较多的上下文切换和调度延时,引起性能问题
35-
* 如果一个线程持有锁,其他的线程就都会挂起,等待持有锁的线程释放锁。
34+
* 在多线程竞争下,加锁、释放锁会导致较多的上下文切换和调度延时,引起性能问题==性能差==
35+
* 如果一个线程持有锁,其他的线程就都会挂起,等待持有锁的线程释放锁:==吞吐量低==
3636
* 如果一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级倒置,引起性能风险
3737

3838
为了优化悲观锁这些问题,就出现了乐观锁:
3939

40-
**假设没有并发冲突,每次不加锁操作同一变量,如果有并发冲突导致失败,则重试直至成功。**
40+
==**假设没有并发冲突,每次不加锁操作同一变量,如果有并发冲突导致失败,则重试直至成功。**==
4141

4242
## CAS(Compare and Swap)原理
4343

@@ -52,7 +52,7 @@ CAS 全称是 compare and swap(比较并且交换),是一种用于在多线程
5252
* 冲突检测
5353
* 数据更新
5454

55-
当多个线程尝试使用 CAS 同时更新同一个变量时,只有一个线程可以更新变量的值,其他的线程都会失败,失败的线程并不会挂起,而是告知这次竞争中失败了,并可以再次尝试。
55+
当多个线程尝试使用 CAS 同时更新同一个变量时,只有一个线程可以更新变量的值,其他的线程都会失败,==失败的线程并不会挂起,而是告知这次竞争中失败了,并可以再次尝试。==
5656

5757
**在不使用锁的情况下保证线程安全,CAS 实现机制中有重要的三个操作数:**
5858

0 commit comments

Comments
 (0)