auto commit
This commit is contained in:
parent
bc0e4abc11
commit
b2114fb151
|
@ -1585,7 +1585,7 @@ ThreadLocal 从理论上讲并不是用来解决多线程并发问题的,因
|
|||
|
||||
互斥同步的进入阻塞状态的开销都很大,应该尽量避免。在许多应用中,共享数据的锁定状态只会持续很短的一段时间。自旋锁的思想是让一个线程在请求一个共享数据的锁时执行忙循环(自旋)一段时间,如果在这段时间内能获得锁,就可以避免进入阻塞状态。
|
||||
|
||||
自选锁虽然能避免进入阻塞状态从而减少开销,但是它需要进行忙循环操作占用 CPU 时间,它只适用于共享数据的锁定状态很短的场景。自旋次数的默认值是 10 次,用户可以使用虚拟机参数 -XX:PreBlockSpin 来更改。
|
||||
自选锁虽然能避免进入阻塞状态从而减少开销,但是它需要进行忙循环操作占用 CPU 时间,它只适用于共享数据的锁定状态很短的场景。
|
||||
|
||||
在 JDK 1.6 中引入了自适应的自旋锁。自适应意味着自旋的次数不再固定了,而是由前一次在同一个锁上的自旋次数及锁的拥有者的状态来决定。
|
||||
|
||||
|
@ -1593,7 +1593,7 @@ ThreadLocal 从理论上讲并不是用来解决多线程并发问题的,因
|
|||
|
||||
锁消除是指对于被检测出不可能存在竞争的共享数据的锁进行消除。
|
||||
|
||||
锁消除主要是通过逃逸分析来支持,如果堆上的共享数据不可能逃逸出去被其它线程访问到,那么就可以把它们当成私有数据对待,也就可以将它们上的锁进行消除。
|
||||
锁消除主要是通过逃逸分析来支持,如果堆上的共享数据不可能逃逸出去被其它线程访问到,那么就可以把它们当成私有数据对待,也就可以将它们的锁进行消除。
|
||||
|
||||
对于一些看起来没有加锁的代码,其实隐式的加了很多锁。例如下面的字符串拼接代码就隐式加了锁:
|
||||
|
||||
|
@ -1603,7 +1603,7 @@ public static String concatString(String s1, String s2, String s3) {
|
|||
}
|
||||
```
|
||||
|
||||
String 是一个不可变的类,Javac 编译器会对 String 的拼接自动优化。在 JDK 1.5 之前,会转化为 StringBuffer 对象的连续 append() 操作,在 JDK 1.5 及以后的版本中,会转化为 StringBuilder 对象的连续 append() 操作,即上面的代码可能会变成下面的样子:
|
||||
String 是一个不可变的类,编译器会对 String 的拼接自动优化。在 JDK 1.5 之前,会转化为 StringBuffer 对象的连续 append() 操作:
|
||||
|
||||
```java
|
||||
public static String concatString(String s1, String s2, String s3) {
|
||||
|
@ -1615,7 +1615,7 @@ public static String concatString(String s1, String s2, String s3) {
|
|||
}
|
||||
```
|
||||
|
||||
每个 StringBuffer.append() 方法中都有一个同步块,锁就是 sb 对象。虚拟机观察变量 sb,很快就会发现它的动态作用域被限制在 concatString() 方法内部。也就是说,sb 的所有引用永远不会“逃逸”到 concatString() 方法之外,其他线程无法访问到它。因此,虽然这里有锁,但是可以被安全地消除掉。
|
||||
每个 append() 方法中都有一个同步块。虚拟机观察变量 sb,很快就会发现它的动态作用域被限制在 concatString() 方法内部。也就是说,sb 的所有引用永远不会“逃逸”到 concatString() 方法之外,其他线程无法访问到它,因此可以进行消除。
|
||||
|
||||
## 锁粗化
|
||||
|
||||
|
@ -1647,8 +1647,6 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态:
|
|||
|
||||
偏向锁的思想是偏向于让第一个获取锁对象的线程,这个线程在之后获取该锁就不再需要进行同步操作,甚至连 CAS 操作也不再需要。
|
||||
|
||||
可以使用 -XX:+UseBiasedLocking=true 开启偏向锁,不过在 JDK 1.6 中它是默认开启的。
|
||||
|
||||
当锁对象第一次被线程获得的时候,进入偏向状态,标记为 1 01。同时使用 CAS 操作将线程 ID 记录到 Mark Word 中,如果 CAS 操作成功,这个线程以后每次进入这个锁相关的同步块就不需要再进行任何同步操作。
|
||||
|
||||
当有另外一个线程去尝试获取这个锁对象时,偏向状态就宣告结束,此时撤销偏向(Revoke Bias)后恢复到未锁定状态或者轻量级锁状态。
|
||||
|
|
|
@ -366,7 +366,7 @@ public int maxProfit(int[] prices) {
|
|||
|
||||
双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。
|
||||
|
||||
**有序数组的 Tow Sum**
|
||||
**有序数组的 Two Sum**
|
||||
|
||||
[Leetcode :167. Two Sum II - Input array is sorted (Easy)](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/)
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* [SET](#set)
|
||||
* [HASH](#hash)
|
||||
* [ZSET](#zset)
|
||||
* [三、字典](#三字典)
|
||||
* [三、数据结构](#三数据结构)
|
||||
* [字典](#字典)
|
||||
* [跳跃表](#跳跃表)
|
||||
* [四、使用场景](#四使用场景)
|
||||
* [缓存](#缓存)
|
||||
* [计数器](#计数器)
|
||||
|
@ -205,7 +207,9 @@ OK
|
|||
2) "982"
|
||||
```
|
||||
|
||||
# 三、字典
|
||||
# 三、数据结构
|
||||
|
||||
## 字典
|
||||
|
||||
以下是 Redis 字典的主要数据结构,从上往下分析,一个 dict 有两个 dictht,一个 dictht 有一个 dictEntry 数组,每个 dictEntry 有 next 指针因此是一个链表结构。从上面的分析可以看出 Redis 的字典是一个基于拉链法解决冲突的哈希表结构。
|
||||
|
||||
|
@ -309,6 +313,24 @@ int dictRehash(dict *d, int n) {
|
|||
}
|
||||
```
|
||||
|
||||
## 跳跃表
|
||||
|
||||
是有序集合的底层实现之一。
|
||||
|
||||
跳跃表是基于多指针有序链表实现的,可以看成多个有序链表。
|
||||
|
||||
<div align="center"> <img src="../pics//beba612e-dc5b-4fc2-869d-0b23408ac90a.png"/> </div><br>
|
||||
|
||||
在查找时,从上层指针开始查找,找到对应的区间之后再到下一层去查找。例如下图演示了查找 22 的过程。
|
||||
|
||||
<div align="center"> <img src="../pics//0ea37ee2-c224-4c79-b895-e131c6805c40.png"/> </div><br>
|
||||
|
||||
与红黑树等平衡树相比,跳跃表具有以下优点:
|
||||
|
||||
- 插入速度非常快速,因为不需要平衡树的旋转操作;
|
||||
- 更容易实现;
|
||||
- 支持无锁操作。
|
||||
|
||||
# 四、使用场景
|
||||
|
||||
## 缓存
|
||||
|
@ -562,13 +584,13 @@ Sentinel(哨兵)可以监听主服务器,并在主服务器进入下线状
|
|||
|
||||
- 可以发布文章;
|
||||
- 可以对文章进行点赞;
|
||||
- 在首页可以按文章的发布时间或者文章的点赞数进行排序显示;
|
||||
- 在首页可以按文章的发布时间或者文章的点赞数进行排序显示。
|
||||
|
||||
## 文章信息
|
||||
|
||||
文章包括标题、作者、赞数等信息,在关系型数据库中很容易构建一张表来存储这些信息,在 Redis 中可以使用 HASH 来存储每种信息以及其对应的值的映射。
|
||||
|
||||
Redis 没有关系型数据库中的表这一概念来将同类型的数据存放在一起,而是使用命名空间的方式来实现这一功能。键名的前面部分存储命名空间,后面部分的内容存储 ID,通常使用 : 来进行分隔。例如下面的 HASH 的键名为 article:92617,其中 article 为命名空间,ID 为 92617。
|
||||
Redis 没有关系型数据库中的表这一概念来将同种类型的数据存放在一起,而是使用命名空间的方式来实现这一功能。键名的前面部分存储命名空间,后面部分的内容存储 ID,通常使用 : 来进行分隔。例如下面的 HASH 的键名为 article:92617,其中 article 为命名空间,ID 为 92617。
|
||||
|
||||
<div align="center"> <img src="../pics//7c54de21-e2ff-402e-bc42-4037de1c1592.png" width="400"/> </div><br>
|
||||
|
||||
|
@ -591,6 +613,7 @@ Redis 没有关系型数据库中的表这一概念来将同类型的数据存
|
|||
- Carlson J L. Redis in Action[J]. Media.johnwiley.com.au, 2013.
|
||||
- [黄健宏. Redis 设计与实现 [M]. 机械工业出版社, 2014.](http://redisbook.com/index.html)
|
||||
- [REDIS IN ACTION](https://redislabs.com/ebook/foreword/)
|
||||
- [Skip Lists: Done Right](http://ticki.github.io/blog/skip-lists-done-right/)
|
||||
- [论述 Redis 和 Memcached 的差异](http://www.cnblogs.com/loveincode/p/7411911.html)
|
||||
- [Redis 3.0 中文版- 分片](http://wiki.jikexueyuan.com/project/redis-guide)
|
||||
- [Redis 应用场景](http://www.scienjus.com/redis-use-case/)
|
||||
|
|
BIN
pics/0ea37ee2-c224-4c79-b895-e131c6805c40.png
Normal file
BIN
pics/0ea37ee2-c224-4c79-b895-e131c6805c40.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
pics/beba612e-dc5b-4fc2-869d-0b23408ac90a.png
Normal file
BIN
pics/beba612e-dc5b-4fc2-869d-0b23408ac90a.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
Loading…
Reference in New Issue
Block a user