Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit df14ba0

Browse filesBrowse files
committed
[A]位运算分析
1 parent b1db89b commit df14ba0
Copy full SHA for df14ba0

File tree

Expand file treeCollapse file tree

2 files changed

+143
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+143
-0
lines changed
Open diff view settings
Collapse file
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.learnjava.concurent;
2+
3+
import java.util.concurrent.atomic.AtomicInteger;
4+
5+
/**
6+
* @Description
7+
* @Author luohaiyang
8+
* @Date 2022/4/24
9+
*/
10+
public class ThreadPoolExecutorDemo {
11+
12+
public static void main(String[] args) {
13+
testThreadPoolExecutorBinaryCalc();
14+
}
15+
16+
17+
/**
18+
* 验证ThreadPoolExecutor中的二进制位运算操作
19+
*/
20+
private static void testThreadPoolExecutorBinaryCalc() {
21+
// System.out.println(ctl.get());
22+
// System.out.println(Integer.toBinaryString(ctlOf(RUNNING, 0)));
23+
// System.out.println(Integer.toBinaryString(RUNNING));
24+
// 修改线程状态-STOP
25+
System.out.println(Integer.toBinaryString(~runStateOf(ctlOf(STOP, 10))));
26+
// 修改线程状态-TERMINATED
27+
// System.out.println(runStateOf(3));
28+
// System.out.println(Integer.toBinaryString(~CAPACITY));
29+
}
30+
31+
private static final int COUNT_BITS = Integer.SIZE - 3;
32+
33+
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
34+
35+
private static final int RUNNING = -1 << COUNT_BITS;
36+
private static final int SHUTDOWN = 0 << COUNT_BITS;
37+
private static final int STOP = 1 << COUNT_BITS;
38+
private static final int TIDYING = 2 << COUNT_BITS;
39+
private static final int TERMINATED = 3 << COUNT_BITS;
40+
41+
private static AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
42+
43+
private static int runStateOf(int c) { return c & ~CAPACITY; }
44+
45+
private static int workerCountOf(int c) { return c & CAPACITY; }
46+
47+
private static int ctlOf(int rs, int wc) { return rs | wc; }
48+
}
Collapse file
+95Lines changed: 95 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
相信看过几个流行框架源码的小伙伴,或多或少都见到过底层代码运用的位运算,不知道有多少是能够一眼看懂了的,一眼看懂了的都是“真大佬”。如果看不懂的话就老老实实的通过二进制分析来看下这些二进制算法的作用。
2+
3+
## 1. JDK1.8 HashMap里运用到的为运算
4+
5+
## 2. Netty里运用的位运算
6+
7+
## 3. JDK ThreadPoolExecutor里的位运算
8+
9+
```java
10+
public class ThreadPoolExecutor extends AbstractExecutorService {
11+
12+
// ... 其他代码省略
13+
14+
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
15+
private static final int COUNT_BITS = Integer.SIZE - 3;
16+
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
17+
18+
private static final int RUNNING = -1 << COUNT_BITS;
19+
private static final int SHUTDOWN = 0 << COUNT_BITS;
20+
private static final int STOP = 1 << COUNT_BITS;
21+
private static final int TIDYING = 2 << COUNT_BITS;
22+
private static final int TERMINATED = 3 << COUNT_BITS;
23+
24+
private static int runStateOf(int c) { return c & ~CAPACITY; }
25+
private static int workerCountOf(int c) { return c & CAPACITY; }
26+
private static int ctlOf(int rs, int wc) { return rs | wc; }
27+
28+
private static boolean runStateLessThan(int c, int s) {
29+
return c < s;
30+
}
31+
32+
private static boolean runStateAtLeast(int c, int s) {
33+
return c >= s;
34+
}
35+
36+
private static boolean isRunning(int c) {
37+
return c < SHUTDOWN;
38+
}
39+
40+
// ... 其他代码省略
41+
}
42+
```
43+
首先看下ctlOf()方法,入参是int rs和int wc,这里rs其实是线程池里线程的状态,而wc表示的时线程数,基于这两个点我们进行位运算分析。
44+
45+
首先看先成变量:
46+
```java
47+
private static final int COUNT_BITS = Integer.SIZE - 3;
48+
private static final int RUNNING = -1 << COUNT_BITS;
49+
```
50+
Integer.SIZE = 32,所以COUNT_BITS = 29,这里RUNNING就是-1的二进制位左移29位,得到的结果就是(提示:-1的二进制是: 1111 1111 1111 1111 ... 三十二位全是1)
51+
```
52+
1110 0000 0000 0000 0000 0000 0000 0000
53+
```
54+
这就是RUNNING的二进制值。
55+
同理我们可以分别得到SHUTDOWN、STOP、TIDYING、TERMINATED的二进制值
56+
```
57+
0000 0000 0000 0000 0000 0000 0000 0000 // SHUTDOWN
58+
0010 0000 0000 0000 0000 0000 0000 0000 // STOP
59+
0100 0000 0000 0000 0000 0000 0000 0000 // TIDYING
60+
0110 0000 0000 0000 0000 0000 0000 0000 // TERMINATED
61+
```
62+
这里其实已经可以看出作者的用意了,就是让高3位作为线程池的状态,低29位用来表示线程数量。对于
63+
```java
64+
private static int ctlOf(int rs, int wc) { return rs | wc; }
65+
// 位运算“或”,遇1得1,否则为0
66+
```
67+
所以ctlOf就表示将rs代表的线程状态和wc代表的线程数计算在同一个32位二进制中,互相不影响。
68+
所以如下:
69+
```java
70+
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
71+
// 1110 0000 0000 0000 0000 0000 0000 0000
72+
```
73+
接着,再来分析下另外两个方法:runStateOf()、workerCountOf(),这两个方法都喝CAPACITY有关,先看下CAPACITY属性
74+
```java
75+
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
76+
// 1 << 29 => 0010 0000 0000 0000 0000 0000 0000 0000
77+
// 1 << 29 - 1 => 0001 1111 1111 1111 1111 1111 1111 1111
78+
79+
80+
private static int runStateOf(int c) { return c & ~CAPACITY; }
81+
// ~CAPACITY => 1110 0000 0000 0000 0000 0000 0000 0000
82+
// 运算“与”表示11得1,否则为0,所以 c & ~CAPACITY实际上就只能操作高三位,
83+
// 也就是只能计算线程状态,并且~CAPACITY表示的是RUNNING时的状态
84+
85+
86+
private static int workerCountOf(int c) { return c & CAPACITY; }
87+
// CAPACITY => 0001 1111 1111 1111 1111 1111 1111 1111
88+
// 所以 c & CAPACITY 就表示只能操作低29位,所以workerCountOf就只能操作线程数
89+
```
90+
这里需要注意的是,runStateOf()和workerCountOf()传入的数字都是需要由:ctlOf()计算返回的,否则计算会出错。
91+
92+
线程池位运算相关验证代码于:
93+
94+
95+
未完待续...

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.