Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

更正 标记-清除算法 #193

Open
wants to merge 53 commits into
base: fix
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
c398353
Merge pull request #153 from crossoverJie/fix
crossoverJie Mar 26, 2019
d3da2cb
:sparkles: Introducing new features.线程池中你不容错过的一些细节
crossoverJie Mar 26, 2019
1e61bc2
:sparkles: 线程池中你不容错过的一些细节
crossoverJie Mar 26, 2019
80f2750
:sparkles: 线程池中你不容错过的一些细节
crossoverJie Mar 26, 2019
81038a8
:sparkles: 线程池中你不容错过的一些细节
crossoverJie Mar 26, 2019
bc49e9d
更正ThreadPoolExecutor.md
sora-zero Mar 31, 2019
5d2fa70
jdk1.8 HashMap treeifyBin 树形化场景描述修改
aaronysj Apr 7, 2019
0159a48
:sparkles: Introducing new features.阻塞队列
crossoverJie Apr 8, 2019
d09056e
:bulb: Documenting source code.
crossoverJie Apr 9, 2019
4ce09f8
:bulb: Documenting source code.
crossoverJie Apr 9, 2019
3763914
:bulb: Documenting source code.
crossoverJie Apr 9, 2019
fe0613a
Merge pull request #158 from AaronYSJ/patch-1
crossoverJie Apr 9, 2019
e8a93ac
:memo: Writing docs.
crossoverJie Apr 9, 2019
35712a9
Merge pull request #155 from sora-zero/patch-2
crossoverJie Apr 9, 2019
b13a7c3
:memo: Writing docs.
crossoverJie Apr 9, 2019
5bd9b3b
:sparkles: 『并发包入坑指北』之阻塞队列
crossoverJie Apr 15, 2019
1f3d10a
:sparkles: 一次分表踩坑实践的探讨
crossoverJie Apr 17, 2019
e8dd616
:sparkles: 自定义countdown
crossoverJie Apr 18, 2019
a8dff3b
:sparkles: 自定义countdown
crossoverJie Apr 18, 2019
93f4229
:bulb: Documenting source code.
crossoverJie Apr 22, 2019
95cb921
:bulb: Documenting source code.
crossoverJie Apr 25, 2019
d703d42
:bulb: Documenting source code.
crossoverJie Apr 25, 2019
70d0a24
:bulb: Documenting source code.
crossoverJie Apr 25, 2019
af04cb2
:bulb: Documenting source code.
crossoverJie Apr 28, 2019
972e15e
:bulb: Documenting source code.
crossoverJie Apr 28, 2019
0970db7
:bulb: Documenting source code.注释线程池
crossoverJie May 17, 2019
89282be
:bulb: Documenting source code.注释线程池
crossoverJie May 17, 2019
58e1378
:bulb: Documenting source code.注释线程池
crossoverJie May 17, 2019
fa4b0f5
:bulb: Documenting source code.注释线程池
crossoverJie May 18, 2019
bc61eb5
:bulb: Documenting source code.注释线程池
crossoverJie May 18, 2019
0feb80d
:bulb: Documenting source code.注释线程池
crossoverJie May 18, 2019
01c7f61
:bulb: Documenting source code.注释线程池
crossoverJie May 18, 2019
a5742f5
:bulb: Documenting source code.注释线程池
crossoverJie May 26, 2019
698b961
:white_check_mark: Adding tests.
crossoverJie Jun 3, 2019
d412dd6
:sparkles: Introducing new features.有返回值的线程
crossoverJie Jun 3, 2019
f7d3888
:sparkles: Introducing new features.有返回值的线程
crossoverJie Jun 3, 2019
fd718a2
:sparkles: Introducing new features.线程池异常处理
crossoverJie Jun 4, 2019
9a35fd5
:sparkles: Introducing new features.线程池异常处理
crossoverJie Jun 5, 2019
b7ab8cb
:ok_hand: Updating code due to code review changes.
crossoverJie Jun 5, 2019
72e867f
:ok_hand: Updating code due to code review changes.
crossoverJie Jun 5, 2019
d328d16
:ok_hand: Updating code due to code review changes.
crossoverJie Jun 8, 2019
9d6cba5
:bug: Fixing a bug.img
crossoverJie Jun 24, 2019
d6516cf
:bug: Fixing a bug.img
crossoverJie Jun 24, 2019
338851e
:bug: Fixing a bug.img
crossoverJie Jun 26, 2019
b92e005
:bug: Fixing a bug.img
crossoverJie Jun 26, 2019
8aca43f
:bug: Fixing a bug.img
crossoverJie Jun 26, 2019
4875950
:white_check_mark: Adding tests.
crossoverJie Jul 3, 2019
ccd6b8f
:white_check_mark: Adding tests.
crossoverJie Jul 19, 2019
e539e33
replace pic
crossoverJie Jul 19, 2019
4bba686
replace pic
crossoverJie Jul 19, 2019
903aa9b
replace pic
crossoverJie Oct 14, 2019
60440b6
:arrow_up: Upgrading dependencies.
crossoverJie Oct 14, 2019
eb782f0
Update GarbageCollection.md
Apr 5, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions 79884.log
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,30 @@ Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):

"Blocked2" #13 prio=5 os_prio=31 tid=0x00007ffd7b08b000 nid=0x5503 waiting for monitor entry [0x00007000083d1000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.crossoverjie.concurrent.ThreadState$Blocked.run(ThreadState.java:59)
- waiting to lock <0x000000079576cd60> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Blocked)
at com.crossoverjie.thread.ThreadState$Blocked.run(ThreadState.java:59)
- waiting to lock <0x000000079576cd60> (a java.lang.Class for com.crossoverjie.thread.ThreadState$Blocked)
at java.lang.Thread.run(Thread.java:748)

"Blocked1" #12 prio=5 os_prio=31 tid=0x00007ffd7b08a000 nid=0x5303 waiting on condition [0x00007000082ce000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.crossoverjie.concurrent.ThreadState$Blocked.run(ThreadState.java:59)
- locked <0x000000079576cd60> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Blocked)
at com.crossoverjie.thread.ThreadState$Blocked.run(ThreadState.java:59)
- locked <0x000000079576cd60> (a java.lang.Class for com.crossoverjie.thread.ThreadState$Blocked)
at java.lang.Thread.run(Thread.java:748)

"Waiting" #11 prio=5 os_prio=31 tid=0x00007ffd7b089800 nid=0x5103 in Object.wait() [0x00007000081cb000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795768db0> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Waiting)
- waiting on <0x0000000795768db0> (a java.lang.Class for com.crossoverjie.thread.ThreadState$Waiting)
at java.lang.Object.wait(Object.java:502)
at com.crossoverjie.concurrent.ThreadState$Waiting.run(ThreadState.java:42)
- locked <0x0000000795768db0> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Waiting)
at com.crossoverjie.thread.ThreadState$Waiting.run(ThreadState.java:42)
- locked <0x0000000795768db0> (a java.lang.Class for com.crossoverjie.thread.ThreadState$Waiting)
at java.lang.Thread.run(Thread.java:748)

"TimeWaiting" #10 prio=5 os_prio=31 tid=0x00007ffd7b82c800 nid=0x4f03 waiting on condition [0x00007000080c8000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.crossoverjie.concurrent.ThreadState$TimeWaiting.run(ThreadState.java:27)
at com.crossoverjie.thread.ThreadState$TimeWaiting.run(ThreadState.java:27)
at java.lang.Thread.run(Thread.java:748)

"Monitor Ctrl-Break" #9 daemon prio=5 os_prio=31 tid=0x00007ffd7a97e000 nid=0x4d03 runnable [0x0000700007fc5000]
Expand Down
2 changes: 1 addition & 1 deletion MD/GarbageCollection.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
### 标记-清除算法

标记清除算法分为两个步骤,标记和清除。
首先将**不需要回收的对象**标记起来,然后再清除其余可回收对象。但是存在两个主要的问题:
首先将**需要回收的对象**标记起来,在标记完成后统一回收所有被标记的对象。但是存在两个主要的问题:
- 标记和清除的效率都不高。
- 清除之后容易出现不连续内存,当需要分配一个较大内存时就不得不需要进行一次垃圾回收。

Expand Down
2 changes: 1 addition & 1 deletion MD/HashMap.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ map.forEach((key,value)->{
> 所以 HashMap 只能在单线程中使用,并且尽量的预设容量,尽可能的减少扩容。

在 `JDK1.8` 中对 `HashMap` 进行了优化:
当 `hash` 碰撞之后写入链表的长度超过了阈值(默认为8),链表将会转换为**红黑树**。
当 `hash` 碰撞之后写入链表的长度超过了阈值(默认为8)并且 `table` 的长度不小于64(否则扩容一次)时,链表将会转换为**红黑树**。

假设 `hash` 冲突非常严重,一个数组后面接了很长的链表,此时重新的时间复杂度就是 `O(n)` 。

Expand Down
2 changes: 1 addition & 1 deletion MD/Synchronize.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public class com.crossoverjie.synchronize.Synchronize {
#### 释放锁
当有另外一个线程获取这个锁时,持有偏向锁的线程就会释放锁,释放时会等待全局安全点(这一时刻没有字节码运行),接着会暂停拥有偏向锁的线程,根据锁对象目前是否被锁来判定将对象头中的 `Mark Word` 设置为无锁或者是轻量锁状态。

偏向锁可以提高带有同步却没有竞争的程序性能,但如果程序中大多数锁都存在竞争时,那偏向锁就起不到太大作用。可以使用 `-XX:-userBiasedLocking=false` 来关闭偏向锁,并默认进入轻量锁。
偏向锁可以提高带有同步却没有竞争的程序性能,但如果程序中大多数锁都存在竞争时,那偏向锁就起不到太大作用。可以使用 `-XX:-UseBiasedLocking` 来关闭偏向锁,并默认进入轻量锁。


### 其他优化
Expand Down
2 changes: 1 addition & 1 deletion MD/ThreadPoolExecutor.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ threadPool.execute(new Job());
1. 获取当前线程池的状态。
2. 当前线程数量小于 coreSize 时创建一个新的线程运行。
3. 如果当前线程处于运行状态,并且写入阻塞队列成功。
4. 双重检查,再次获取线程状态;如果线程状态变了(非运行状态)就需要从阻塞队列移除任务,并尝试判断线程是否全部执行完毕。同时执行拒绝策略。
4. 双重检查,再次获取线程池状态;如果线程池状态变了(非运行状态)就需要从阻塞队列移除任务,并尝试判断线程是否全部执行完毕。同时执行拒绝策略。
5. 如果当前线程池为空就新创建一个线程并执行。
6. 如果在第三步的判断为非运行状态,尝试新建线程,如果失败则执行拒绝策略。

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
- [ConcurrentHashMap 的实现原理](https://github.com/crossoverJie/JCSprout/blob/master/MD/ConcurrentHashMap.md)
- [如何优雅的使用和理解线程池](https://github.com/crossoverJie/JCSprout/blob/master/MD/ThreadPoolExecutor.md)
- [深入理解线程通信](https://github.com/crossoverJie/JCSprout/blob/master/MD/concurrent/thread-communication.md)
- [一个线程罢工的诡异事件](docs/thread/thread-gone.md)
- [线程池中你不容错过的一些细节](docs/thread/thread-gone2.md)
- [『并发包入坑指北』之阻塞队列](docs/thread/ArrayBlockingQueue.md)

### JVM
- [Java 运行时内存划分](https://github.com/crossoverJie/JCSprout/blob/master/MD/MemoryAllocation.md)
Expand Down Expand Up @@ -81,6 +84,7 @@
- [MySQL 索引原理](https://github.com/crossoverJie/JCSprout/blob/master/MD/MySQL-Index.md)
- [SQL 优化](https://github.com/crossoverJie/JCSprout/blob/master/MD/SQL-optimization.md)
- [数据库水平垂直拆分](https://github.com/crossoverJie/JCSprout/blob/master/MD/DB-split.md)
- [一次分表踩坑实践的探讨](docs/db/sharding-db.md)

### 数据结构与算法
- [红包算法](https://github.com/crossoverJie/JCSprout/blob/master/src/main/java/com/crossoverjie/red/RedPacket.java)
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

**欢迎我的关注公众号一起交流:**

![](https://ws3.sinaimg.cn/large/006tKfTcgy1fsuvb4ebtmj30760760t7.jpg)
![](https://crossoverjie.top/uploads/weixinfooter1.jpg)

</div>

Expand Down
4 changes: 4 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
- [ConcurrentHashMap 的实现原理](thread/ConcurrentHashMap.md)
- [如何优雅的使用和理解线程池](thread/ThreadPoolExecutor.md)
- [深入理解线程通信](thread/thread-communication.md)
- [一个线程罢工的诡异事件](thread/thread-gone.md)
- [线程池中你不容错过的一些细节](thread/thread-gone2.md)
- [『并发包入坑指北』之阻塞队列](thread/ArrayBlockingQueue.md)

- JVM

Expand Down Expand Up @@ -56,6 +59,7 @@
- [MySQL 索引原理](db/MySQL-Index.md)
- [SQL 优化](db/SQL-optimization.md)
- [数据库水平垂直拆分](db/DB-split.md)
- [一次分表踩坑实践的探讨](db/sharding-db.md)

- 数据结构与算法

Expand Down
16 changes: 8 additions & 8 deletions docs/algorithm/Consistent-Hash.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,30 @@

一致 Hash 算法是将所有的哈希值构成了一个环,其范围在 `0 ~ 2^32-1`。如下图:

![](https://ws1.sinaimg.cn/large/006tNc79gy1fn8kbmd4ncj30ad08y3yn.jpg)
![](https://i.loli.net/2019/06/26/5d13931ace0d988790.jpg)

之后将各个节点散列到这个环上,可以用节点的 IP、hostname 这样的唯一性字段作为 Key 进行 `hash(key)`,散列之后如下:

![](https://ws3.sinaimg.cn/large/006tNc79gy1fn8kf72uwuj30a40a70t5.jpg)
![](https://i.loli.net/2019/06/26/5d13931b42d3941564.jpg)

之后需要将数据定位到对应的节点上,使用同样的 `hash 函数` 将 Key 也映射到这个环上。

![](https://ws3.sinaimg.cn/large/006tNc79gy1fn8kj9kd4oj30ax0aomxq.jpg)
![](https://i.loli.net/2019/06/26/5d13931b811c782755.jpg)

这样按照顺时针方向就可以把 k1 定位到 `N1节点`,k2 定位到 `N3节点`,k3 定位到 `N2节点`。

### 容错性
这时假设 N1 宕机了:

![](https://ws3.sinaimg.cn/large/006tNc79gy1fn8kl9pp06j30a409waaj.jpg)
![](https://i.loli.net/2019/06/26/5d13931ba4a0869451.jpg)

依然根据顺时针方向,k2 和 k3 保持不变,只有 k1 被重新映射到了 N3。这样就很好的保证了容错性,当一个节点宕机时只会影响到少少部分的数据。

### 拓展性

当新增一个节点时:

![](https://ws1.sinaimg.cn/large/006tNc79gy1fn8kp1fc9xj30ca0abt9c.jpg)
![](https://i.loli.net/2019/06/26/5d13931bc818391034.jpg)

在 N2 和 N3 之间新增了一个节点 N4 ,这时会发现受印象的数据只有 k3,其余数据也是保持不变,所以这样也很好的保证了拓展性。

Expand All @@ -49,14 +49,14 @@

当节点较少时会出现数据分布不均匀的情况:

![](https://ws2.sinaimg.cn/large/006tNc79gy1fn8krttekbj30c10a5dg5.jpg)
![](https://i.loli.net/2019/06/26/5d13931c0392a99489.jpg)

这样会导致大部分数据都在 N1 节点,只有少量的数据在 N2 节点。

为了解决这个问题,一致哈希算法引入了虚拟节点。将每一个节点都进行多次 hash,生成多个节点放置在环上称为虚拟节点:

![](https://ws2.sinaimg.cn/large/006tNc79gy1fn8ktzuswkj30ae0abdgb.jpg)
![](https://i.loli.net/2019/06/26/5d13931c3e2f146589.jpg)

计算时可以在 IP 后加上编号来生成哈希值。

这样只需要在原有的基础上多一步由虚拟节点映射到实际节点的步骤即可让少量节点也能满足均匀性。
这样只需要在原有的基础上多一步由虚拟节点映射到实际节点的步骤即可让少量节点也能满足均匀性。
14 changes: 7 additions & 7 deletions docs/algorithm/LRU-cache.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![](https://ws1.sinaimg.cn/large/006tNc79gy1fq3fey7n97j31340o8myw.jpg)
![](https://i.loli.net/2019/06/26/5d13931b1ef2443865.jpg)

## 前言
LRU 是 `Least Recently Used` 的简写,字面意思则是`最近最少使用`。
Expand Down Expand Up @@ -676,7 +676,7 @@ public class LRUMap<K, V> {

### 初始化时

![](https://ws1.sinaimg.cn/large/006tNc79gy1fq3h4xsf4cj30dh09hglr.jpg)
![](https://i.loli.net/2019/06/26/5d13931b9416744111.jpg)

### 写入数据时

Expand All @@ -685,24 +685,24 @@ LRUMap<String,Integer> lruMap = new LRUMap(3) ;
lruMap.put("1",1) ;
```

![](https://ws4.sinaimg.cn/large/006tNc79gy1fq3h892nalj30ef09jdg2.jpg)
![](https://i.loli.net/2019/06/26/5d13931c136d238581.jpg)


```java
lruMap.put("2",2) ;
```
![](https://ws3.sinaimg.cn/large/006tNc79gy1fq3hayffy1j30jr0b6q3a.jpg)
![](https://i.loli.net/2019/06/26/5d1393217488285452.jpg)


```java
lruMap.put("3",3) ;
```
![](https://ws4.sinaimg.cn/large/006tNc79gy1fq3hcfq95pj30gp0bot93.jpg)
![](https://i.loli.net/2019/06/26/5d139321e34f996391.jpg)

```java
lruMap.put("4",4) ;
```
![](https://ws1.sinaimg.cn/large/006tNc79gy1fq3hfl5r8ij30kn0b374s.jpg)
![](https://i.loli.net/2019/06/26/5d139322609e214433.jpg)


### 获取数据时
Expand All @@ -713,7 +713,7 @@ lruMap.put("4",4) ;
Integer integer = lruMap.get("2");
```

![](https://ws2.sinaimg.cn/large/006tNc79gy1fq3hjbou5pj30k70aj3yy.jpg)
![](https://i.loli.net/2019/06/26/5d139322ea89567527.jpg)

通过以上几张图应该是很好理解数据是如何存放的了。

Expand Down
Loading