Skip to content

Commit baccefc

Browse files
author
代码风水师
committed
1.完善了基于Redis实现分布式锁;2.review的部分集合源码分析
1 parent c2238a7 commit baccefc

File tree

9 files changed

+125
-38
lines changed

9 files changed

+125
-38
lines changed

README.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
### 一、:bullettrain_side::railway_car::railway_car::railway_car:集合框架源码分析
88
* [集合框架 (第 01 篇) 源码分析:Collection<E> 框架总览](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/collection/JavaCollections.md)
99
* [集合框架 (第 02 篇) 源码分析:Map<K,V > 框架总览](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/collection/JavaMaps.md)
10-
* [集合框架 (第 03 篇) 源码分析:ArrayList](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/collection/ArrayList.md)
10+
* [集合框架 (第 03 篇) 源码分析:ArrayList<E>](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/collection/ArrayList.md)
1111
* [集合框架 (第 04 篇) 源码分析:LinkedList](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/collection/LinkedList.md)
1212
* [集合框架 (第 05 篇) 源码分析:Map<K, V>接口与其内部接口Entry<K,V>](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/collection/Map.Entry1.7v.md)
1313
* [集合框架 (第 06 篇) 源码分析:哈希冲突(哈希碰撞)与解决算法](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/collection/HashConflictsAndResolve.md)
@@ -138,26 +138,29 @@
138138
* [分布式系统 (第 11 篇) 精讲:设计分布式锁](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/distribution/DistributedLock.md)
139139
* 分布式系统 (第 12 篇) 精讲:分布式session/token一致性设计
140140
* 分布式系统 (第 13 篇) 精讲:分布式事务
141-
* 分布式系统 (第 14 篇) 精讲:分布式高并发的支持与控制
142-
* 分布式系统 (第 15 篇) 精讲:分布式下悲观锁和乐观锁的实现
141+
* 分布式系统 (第 14 篇) 精讲:分布式任务调度
142+
* 分布式系统 (第 15 篇) 精讲:分布式高并发的支持与控制
143143
* 分布式系统 (第 16 篇) 精讲:分布式支付框架的实现
144144

145145

146146
### 十、:microscope::microscope::microscope:微服务
147-
* 微服务 (第 01 篇) 精讲:什么是微服务?
148-
* 微服务 (第 01 篇) 精讲:服务建模
149-
* 微服务 (第 01 篇) 精讲:服务拆分
150-
* 微服务 (第 01 篇) 精讲:微服务的核心 -- 服务治理(服务注册与发现中心)
151-
* 微服务 (第 01 篇) 精讲:网关Gateway
152-
* 微服务 (第 01 篇) 精讲:路由Routing
153-
* 微服务 (第 01 篇) 精讲:负载均衡算法
154-
* 微服务 (第 01 篇) 精讲:服务熔断、服务隔离、服务限流、服务降级、快速失败
155-
* 微服务 (第 01 篇) 精讲:SpringCloud
147+
* 微服务 (第 01 篇) 精讲:微服务与SOA
148+
* 微服务 (第 02 篇) 精讲:服务建模
149+
* 微服务 (第 03 篇) 精讲:服务拆分
150+
* 微服务 (第 04 篇) 精讲:微服务的核心 -- 服务治理(服务注册与发现中心)
151+
* 微服务 (第 05 篇) 精讲:服务网关Gateway
152+
* 微服务 (第 05 篇) 精讲:配置中心
153+
* 微服务 (第 06 篇) 精讲:路由Routing
154+
* 微服务 (第 07 篇) 精讲:负载均衡算法
155+
* 微服务 (第 08 篇) 精讲:服务限流、服务隔离、服务熔断、服务降级、快速失败
156+
* 微服务 (第 09 篇) 精讲:容器化
157+
* 微服务 (第 10 篇) 精讲:SpringCloud
156158

157159

158160
### 十一、:bicyclist::horse_racing::snowboarder:高并发与高可用
159161
* 高并发与高可用 (第 01 篇) 精讲:全局id生成算法
160162
* 高并发与高可用 (第 01 篇) 精讲:如何实现请求幂等性
163+
* 高并发与高可用 (第 01 篇) 精讲:常见的负载均衡算法
161164
* 高并发与高可用 (第 01 篇) 精讲:如何防止网络抖动产生的重复建单
162165
* 高并发与高可用 (第 01 篇) 精讲:如何度过服务器重启后的连接风暴
163166
* 高并发与高可用 (第 01 篇) 精讲:数据持久化 + ACK + 补偿重试+请求幂等性+防重设计

resource/markdown/collection/ArrayList.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
***
88
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">一、ArrayList</h3>
99

10-
> ArrayList是动态数组,其动态性体现在能够`动态扩容、缩容`。(其原理是构建一个新Object数组,将原数组复制进去。借助 `Arrays.copyOf(T[] original, int newLength))`
10+
> ArrayList是动态数组,其动态性体现在能够`动态扩容``动态缩容`。(其原理是构建一个新Object数组,将原数组复制进去。借助 `Arrays.copyOf(T[] original, int newLength))`
1111
1212
> ![ArrayList继承关系](https://i.loli.net/2018/12/09/5c0cbffb79b69.png)
1313
@@ -73,6 +73,7 @@ private void grow(int minCapacity) {
7373
#### 1.2、在指定位子添加方法 public void `add(int index, E element)`
7474

7575
```java
76+
// 注意:在指定 index 位置添加元素,并不会覆盖该处的元素,而是 index位置及其之后的元素后移
7677
public void add(int index, E element) {
7778
// 只要有index,必定会检查range
7879
rangeCheckForAdd(index);
@@ -127,7 +128,17 @@ private void fastRemove(int index) {
127128
}
128129
```
129130

131+
:bomb::bomb::bomb:注意:
132+
133+
1. 如果存在多个对象o,仅仅删除距离 index = 0 处最近的一个元素;
134+
2. 元素被删除后,该位置不会空出来,后面的元素会前移。
135+
136+
所以 `ArrayList` 适合读多删少场景。
137+
138+
139+
130140
#### 3、重新设置指定index位置的元素值 public E `set(int index, E element)`
141+
131142
```java
132143
public E set(int index, E element) {
133144
// 有index,必检查

resource/markdown/collection/HashConflictsAndResolve.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
4141
#### 2.3、:anchor:链地址法(链表法):heavy_check_mark:
4242

43-
![链表法](http://pgq1yfr0p.bkt.clouddn.com/image/java/collection/HashBucket.png)
44-
4543
>当多个元素产生哈希冲突时,它们的哈希码是一定相同,落脚的哈希槽也相同。将它们通过地址引用一一相连,也就是形成 **链表** 的形式。这样它们既可以存储,又不会占用其他哈希槽的位置。这种通过**链表**形式解决**哈希冲突**的算法称为**链表法**。由不同元素、相同哈希码经过组织形成的数据结构称为 **哈希桶**Bucket,或者说这个容器是 **哈希桶****哈希槽**的位置也就是**哈希桶号**
4644
4745
#### 2.4、建立公共溢出区

resource/markdown/collection/HashMap1.7v.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">一、继承关系</h3>
44

5-
![HashMap1.7vExtend](http://pgq1yfr0p.bkt.clouddn.com/image/java/collectionHashMap1.7vExtend.png)
5+
![HashMap1.7vExtend](https://i.loli.net/2019/02/20/5c6d2069aef34.png)
66

77
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">二、数据结构</h3>
88

resource/markdown/collection/LinkedList.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void linkLast(E e) {
8888
}
8989
```
9090

91-
添加元素到头部,操作于此类似
91+
添加元素到头部,操作与此类似
9292

9393
:star::star::star::star::star:
9494
<h4 style="padding-bottom:6px; color:#E74C3C;">重点:添加元素到指定index位置</h4>

resource/markdown/collection/Map.Entry1.7v.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">一、Map接口</h3>
44

5-
> **Map接口**是整个 **Key-Value** 存储容器的核心。它 ****()(xíng)**** 定义了 **Key-Value** 结构的容器框架。**Map**不会像 **数组** 中元素那样可以单独存放,到像似 `LinkedList` 中的节点自定义,那么特殊的节点一定需要特定的来描述。在 `jdk1.7` 及其之前的版本,Map的作者将其节点描述为 **Entry** ,Entry不是 ~~入口~~~~大门~~,它在这里称为 **项目****条目** ,下文简称为 ******Map** 中的每个节点称为 `一项`
5+
> **Map接口**是整个 **Key-Value** 存储容器的核心。它 ****()(xíng)**** 定义了 **Key-Value** 结构的容器框架。**Map**不会像 **数组** 中元素那样可以单独存放,到像似 `LinkedList` 中的节点自定义,那么特殊的节点一定需要特殊的定义来描述。在 `jdk1.7` 及其之前的版本,Map的作者将其节点描述为 **Entry** ,Entry不是 ~~入口~~~~大门~~,它在这里称为 **项目****条目** ,下文简称为 ******Map** 中的每个节点称为 `一项`
66
77
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">二、Map.Entry</h3>
88

@@ -27,7 +27,7 @@ int hashCode()
2727

2828
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">三、Map中的方法</h3>
2929

30-
> **方法** 意味着 行为。下面Map的方法意味着整个Map框架具有最基本的什么样的 **功能**。明白这些方法,就掌握了Map框架核心操作功能。
30+
> **方法** 意味着 行为。下面Map的方法意味着整个Map框架具有最基本的、什么样的 **功能**。明白这些方法,就掌握了Map框架核心操作功能。
3131
3232
```java
3333
// 返回 map 中键值对的数量

resource/markdown/distribution/DistributedLock.md

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ WHERE t0.id = 1001 AND t0.node_number != 2;
5656
**释放锁:**
5757

5858
```mysql
59-
DELETE FROM distribution_lock WHERE id = 1001;
59+
DELETE FROM distribution_lock WHERE id = 1001 AND t0.node_number = 1;
6060
```
6161

6262

@@ -84,60 +84,101 @@ DELETE FROM distribution_lock WHERE id = 1001;
8484
**获取锁**
8585

8686
```shell
87-
127.0.0.1:6379> SETNX lock:1001 192.168.2.104
87+
127.0.0.1:6379> SETNX lock:1001 uuid
8888
```
8989

90-
巧用 `SETNX` 命令,其中 `value` 设置唯一标识,比如 `ip+线程id+时间戳``UUID`诸如此类,如果返回 `1` 表示获取锁成功,否则获取锁失败;
90+
巧用 `SETNX` 命令,其中 `value` 为唯一标识,比如 `ip+线程id+时间戳``UUID`诸如此类,如果返回 `1` 表示获取锁成功,否则获取锁失败;
9191

9292

9393

9494
**设置锁超时时间**
9595

9696
```shell
97-
127.0.0.1:6379> expire lock:1001 30
97+
127.0.0.1:6379> expire lock:1001 5
9898
```
9999

100100
如果返回 `1` 表示设置锁超时成功,否则失败;
101101

102102

103103

104-
**锁过期检查**
104+
##### 获取将直接使用以下命令代替上面两条命令:
105105

106106
```shell
107-
127.0.0.1:6379> GET lock:1001
107+
127.0.0.1:6379> SET lock:1001 uuid EX 5 NX
108108
```
109109

110-
如果获得的 `value` 和之前设置的 `value` 说明锁有效,提交事务;否则锁过期,业务回滚;
111110

112111

113-
114-
**释放锁**
112+
**锁过期检查**
115113

116114
```shell
117-
127.0.0.1:6379> DEL lock:1001
115+
127.0.0.1:6379> GET lock:1001
118116
```
119117

118+
如果获得的 `value` 和之前设置的 `value` 一致,说明锁有效,业务提交;否则锁过期,业务回滚;
120119

121120

122-
注意: 防止误删 `key` ,使用以下伪代码演示:
123121

124-
```java
122+
**释放锁** Redis的事务不像MySQL的事务那样强大,所以释放锁时要防止误删 `key` ,使用Lua脚本来操作:
125123

124+
```java
125+
/**
126+
* 释放分布式锁
127+
*
128+
* @param key key
129+
* @param value value
130+
* @return 主动成功释放锁返回 true,否则返回false
131+
*/
132+
public boolean release(String key, String value) {
133+
// Null check
134+
Assert.notNull(key, "The key is not allowed to be null");
135+
Assert.notNull(value, "The value is not allowed to be null");
136+
137+
// result 表示是否删除指定的 key,1表示是,0表示否
138+
long result = 0;
139+
140+
try {
141+
String lua = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then \n" +
142+
" return redis.call(\"del\",KEYS[1])\n" +
143+
" else \n" +
144+
" return 0\n" +
145+
" end";
146+
147+
result = (Long) jedis.evalsha(jedis.scriptLoad(lua),
148+
Collections.singletonList(key),
149+
Collections.singletonList(value));
150+
151+
} catch (Exception e) {
152+
e.printStackTrace();
153+
} finally {
154+
if (jedis != null) {
155+
try {
156+
jedis.close();
157+
} catch (Exception e) {
158+
e.printStackTrace();
159+
}
160+
}
161+
}
162+
163+
return result == 1;
164+
}
126165
```
127166

128167

129168

130-
131-
132169
---
133170

134171
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">三、基于Zookeeper实现分布式锁</h3>
135172

136173
**获取锁**
137174

138-
175+
// TODO
139176

140177

141178

142179
**释放锁**
143180

181+
182+
183+
// TODO
184+

resource/markdown/micro-service/MicroService.md

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">微服务</h3>
2+
3+
![微服务]()
4+
5+
*微服务* 是一种架构风格,全称是 **微服务架构** ,英文名 *Microservice Architecture*
6+
7+
8+
9+
不一定是单机支撑不了整个应用,而更多强调的是业务上的拆分。
10+
11+
12+
13+
14+
15+
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">SOA</h3>
16+
17+
**SOA***Service-oriented architecture* 简写,中文名称 **面向服务的架构** ,一种软件设计风格,通过网络通信协议,应用程序组件向其他组件提供服务。面向服务的体系结构的基本原则是独立于供应商、产品和技术的。服务是一个独立的功能单元,可以远程访问、独立操作和更新,例如在线检索信用卡对账单。
18+
19+
20+
21+
根据SOA的许多定义之一,服务有四个属性:
22+
23+
1. 它在逻辑上表示具有指定结果的业务活动;
24+
2. 它是独立的;
25+
3. 对于消费者来说,这是一个黑盒;
26+
4. 它可能由其他基础服务组成。
27+
28+
可以结合使用不同的服务来提供大型软件应用程序的功能,[5]SOA与模块化编程共享的原则。面向服务的体系结构集成了分布式、单独维护和部署的软件组件。它是由技术和标准支持的,这些技术和标准促进了组件在网络上的通信和合作,特别是在IP网络上。
29+
30+
31+
32+
在SOA中,服务使用协议来描述如何使用描述元数据传递和解析消息。此元数据描述了服务的功能特性和服务质量特性。面向服务的体系结构旨在允许用户组合大量功能以形成纯粹从现有服务构建的应用程序,并以特殊方式组合它们。服务向请求者提供了一个简单的接口,它抽象出充当黑盒的底层复杂性。其他用户也可以在不了解其内部实现的情况下访问这些独立的服务。
33+
34+
35+
36+
参考资料:
37+
38+
[Wikipedia-Service-oriented architecture](https://en.wikipedia.org/wiki/Service-oriented_architecture)

0 commit comments

Comments
 (0)