Skip to content

Commit 4cab64e

Browse files
committed
Add Stage 3 Lesson 3
1 parent c42bf5f commit 4cab64e

File tree

12 files changed

+357
-0
lines changed

12 files changed

+357
-0
lines changed

「一入 Java 深似海 」/代码/segmentfault/deep-in-java/stage-3/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<modules>
1515
<module>stage-3-lesson-1</module>
1616
<module>stage-3-lesson-2</module>
17+
<module>stage-3-lesson-3</module>
1718
</modules>
1819
<packaging>pom</packaging>
1920

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>stage-3</artifactId>
7+
<groupId>com.segmentfault</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>stage-3-lesson-3</artifactId>
13+
<name>「一入 Java 深似海 」系列 :: 第三期 :: 第三节</name>
14+
15+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
public class AcquireAndReleaseDemo {
4+
5+
public static void main(String[] args) {
6+
// Lock 机制
7+
// 获得 Acquire
8+
// Thread 进入 synchronized -> 获得锁
9+
// 释放 Release
10+
// 1. 当 Thread(hold lock),调用 Object#wait() 时候
11+
// 2. Thread park -> LockSupport.park(Object)
12+
// 3. Condition#await()
13+
// 4. 运行期异常,Thread 消亡
14+
// 5. Java 9 自旋 Thread.onSpinWait();
15+
// 6. Thread.yield();
16+
17+
// 所谓的公平(Fair)和非公平(Nonfair、unfair)
18+
// 公平(Fair)线程 FIFO
19+
// 非公平(Nonfair)线程随线程调度
20+
// 最佳实践:在创建线程时,除非必要,不要调整线程优先级(Priority)
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import sun.misc.Unsafe;
4+
5+
import java.lang.invoke.MethodHandles;
6+
import java.lang.invoke.VarHandle;
7+
import java.lang.reflect.Field;
8+
import java.security.AccessController;
9+
import java.security.PrivilegedActionException;
10+
import java.security.PrivilegedExceptionAction;
11+
import java.util.concurrent.atomic.AtomicBoolean;
12+
import java.util.concurrent.atomic.AtomicLong;
13+
14+
public class AtomicDemo {
15+
16+
public static void main(String[] args) throws Exception {
17+
// CAS 是一种相对(MB)较重的比较,轻量级的锁(标量)
18+
19+
getUnsafe();
20+
21+
// volatile 修饰复杂对象类型时,不具备被传递到字段安全
22+
}
23+
24+
private static void demoAtomicLong() {
25+
// long 表示 64位(8字节),高和低两端
26+
// long 并非线程安全,就是 volatile(高和低操作时,至少两次操作)
27+
AtomicLong l = new AtomicLong();
28+
// set 和 get 通过 JVM 特殊操作,不在直接写入和获取
29+
}
30+
31+
private static void demoAtomicInteger() {
32+
// int 表示 int(32), char(16), short(16), byte(8), boolean(1)
33+
// AtomicInteger 内部使用 int 作为变量标识,1 表示 true, 0 表示 false
34+
// AtomicInteger set 和 get 操作均为 volatile 语义(MB)
35+
// AtomicInteger CAS Unsafe(Java 8) 和 VarHandle(Java 9+)
36+
}
37+
38+
private static void demoAtomicBoolean() {
39+
AtomicBoolean b = new AtomicBoolean();
40+
// AtomicBoolean 内部使用 int 作为变量标识,1 表示 true, 0 表示 false
41+
// AtomicBoolean set 和 get 操作均为 volatile 语义(MB)
42+
// AtomicBoolean CAS Unsafe(Java 8) 和 VarHandle(Java 9+)
43+
}
44+
45+
private static void getVarHandle() {
46+
MethodHandles.Lookup l = MethodHandles.lookup();
47+
}
48+
49+
private static void getUnsafe() throws PrivilegedActionException {
50+
// 无法通过正常方法调用
51+
// Unsafe unsafe = Unsafe.getUnsafe();
52+
53+
// https://github.com/mercyblitz/confucius-commons/blob/master/confucius-commons-lang/src/main/java/org/confucius/commons/lang/misc/UnsafeUtils.java
54+
final PrivilegedExceptionAction<Unsafe> action = new PrivilegedExceptionAction<Unsafe>() {
55+
public Unsafe run() throws Exception {
56+
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
57+
theUnsafe.setAccessible(true);
58+
return (Unsafe) theUnsafe.get(null);
59+
}
60+
};
61+
62+
Unsafe unsafe = AccessController.doPrivileged(action);
63+
64+
if (unsafe == null) {
65+
throw new NullPointerException();
66+
}
67+
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.concurrent.CountDownLatch;
4+
import java.util.concurrent.ExecutorService;
5+
import java.util.concurrent.Executors;
6+
7+
public class CountDownLatchDemo {
8+
9+
public static void main(String[] args) throws InterruptedException {
10+
// 4 -> 3 -> 2 -> 1
11+
CountDownLatch latch = new CountDownLatch(4); // 4 个计数
12+
ExecutorService executorService = Executors.newFixedThreadPool(3); // 线程数 3
13+
14+
for (int i = 0; i < 3; i++) { // 启动3个线程
15+
executorService.submit(() -> {
16+
try {
17+
echoThread();
18+
latch.countDown(); // -1
19+
} catch (Exception e) {
20+
e.printStackTrace();
21+
}
22+
});
23+
}
24+
25+
Thread.sleep(5 * 100);
26+
27+
// 当 count 数量等于 0,才会释放
28+
// 4-3 == 1 !=0
29+
System.out.println("CountDownLatch 剩余数量:" + latch.getCount());
30+
latch.await(); // await 类似 wait() -> join
31+
32+
// 关闭线程池
33+
executorService.shutdown();
34+
35+
}
36+
37+
private static void echoThread() {
38+
System.out.printf("当前线程[%s]正在执行...\n", Thread.currentThread().getName());
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.concurrent.BrokenBarrierException;
4+
import java.util.concurrent.CyclicBarrier;
5+
import java.util.concurrent.ExecutorService;
6+
import java.util.concurrent.Executors;
7+
8+
public class CyclicBarrierDemo {
9+
10+
public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
11+
12+
CyclicBarrier cb = new CyclicBarrier(4);
13+
14+
ExecutorService executorService = Executors.newFixedThreadPool(3);
15+
16+
for (int i = 0; i < 3; i++) {
17+
executorService.submit(() -> {
18+
try {
19+
echoThread();
20+
cb.await(); // await() 让计数 -1
21+
} catch (Exception e) {
22+
e.printStackTrace();
23+
}
24+
});
25+
}
26+
27+
Thread.sleep(5 * 100);
28+
29+
// 当 count 数量等于 0,才会释放
30+
// 4 - 3 == 1 !=0
31+
// 再次 await() -1 => 4 - 3 - 1 = 0
32+
System.out.println(cb.getNumberWaiting());
33+
cb.await();
34+
System.out.println(cb.getNumberWaiting());
35+
36+
// // reset() 操作是恢复计数 0 -> 4
37+
cb.reset();
38+
System.out.println(cb.getNumberWaiting());
39+
//
40+
// 关闭线程池
41+
executorService.shutdown();
42+
43+
}
44+
45+
46+
private static void echoThread() {
47+
System.out.printf("当前线程[%s]正在执行...\n", Thread.currentThread().getName());
48+
}
49+
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.concurrent.TimeUnit;
4+
import java.util.concurrent.locks.Condition;
5+
import java.util.concurrent.locks.Lock;
6+
import java.util.concurrent.locks.ReentrantLock;
7+
8+
public class ReentrantLockDemo {
9+
10+
public static void main(String[] args) {
11+
lockOpsMethods();
12+
}
13+
14+
private static void lockOpsMethods() {
15+
ReentrantLock lock = new ReentrantLock();
16+
int count = lock.getHoldCount();
17+
System.out.printf("在 lock() 方法调用之前的线程[%s]重进入数:%d\n", Thread.currentThread().getName(), count);
18+
lock(lock, 100);
19+
}
20+
21+
private static void lock(ReentrantLock lock, int times) {
22+
23+
if (times < 1) {
24+
return;
25+
}
26+
27+
lock.lock();
28+
29+
try {
30+
// times-- load, minus 1
31+
lock(lock, --times);
32+
System.out.printf("第%s次在 lock() 方法调用之后的线程[%s]重进入数:%d\n",
33+
times+1,
34+
Thread.currentThread().getName(),
35+
lock.getHoldCount());
36+
} finally {
37+
lock.unlock();
38+
}
39+
40+
}
41+
42+
private static void conditionObject() {
43+
Lock lock = new ReentrantLock();
44+
// 条件变量包括条件,同时它又是线程通讯媒介
45+
Condition condition = lock.newCondition();
46+
try {
47+
condition.await();
48+
} catch (InterruptedException e) {
49+
e.printStackTrace();
50+
}
51+
}
52+
53+
private static void tryLockInTimeout() {
54+
Lock lock = new ReentrantLock();
55+
56+
try {
57+
if (lock.tryLock(3, TimeUnit.SECONDS)) { // 当前仅当在规定的时间内获得锁
58+
// Lock API 语义补充了 synchronized 原语的不足
59+
// TODO Add some logic
60+
}
61+
} catch (InterruptedException e) {
62+
// 重置中止状态(防止被中途清除 interrupt 状态)
63+
Thread.currentThread().interrupt();
64+
// logger error message
65+
}
66+
}
67+
68+
private static void synchronizedStatement() {
69+
// 假设出现死锁或者饥饿
70+
synchronized (ReentrantLockDemo.class) {
71+
72+
if (3 > 2) { // 条件
73+
try {
74+
ReentrantLockDemo.class.wait(); // Object 线程通讯方法
75+
} catch (InterruptedException e) {
76+
// logger error message
77+
}
78+
}
79+
}
80+
}
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.concurrent.locks.Lock;
4+
import java.util.concurrent.locks.ReadWriteLock;
5+
import java.util.concurrent.locks.ReentrantReadWriteLock;
6+
7+
public class ReentrantReadWriteLockDemo {
8+
9+
public static void main(String[] args) {
10+
11+
ReadWriteLock lock = new ReentrantReadWriteLock();
12+
13+
Lock readLock = lock.readLock();
14+
15+
Lock writeLock = lock.writeLock();
16+
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.concurrent.*;
4+
5+
public class SemaphoreDemo {
6+
7+
public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
8+
9+
Semaphore cb = new Semaphore(4);
10+
11+
ExecutorService executorService = Executors.newFixedThreadPool(3);
12+
13+
for (int i = 0; i < 3; i++) {
14+
executorService.submit(() -> {
15+
try {
16+
echoThread();
17+
cb.acquire(); // await() 让计数 -1
18+
} catch (Exception e) {
19+
e.printStackTrace();
20+
}
21+
});
22+
}
23+
24+
Thread.sleep(5 * 100);
25+
26+
// 当 count 数量等于 0,才会释放
27+
// 4 - 3 == 1 !=0
28+
// 再次 await() -1 => 4 - 3 - 1 = 0
29+
//
30+
// 关闭线程池
31+
executorService.shutdown();
32+
33+
}
34+
35+
36+
private static void echoThread() {
37+
System.out.printf("当前线程[%s]正在执行...\n", Thread.currentThread().getName());
38+
}
39+
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.concurrent.locks.Lock;
4+
import java.util.concurrent.locks.StampedLock;
5+
6+
public class StampedLockDemo {
7+
8+
public static void main(String[] args) {
9+
// Java 1.8 之后提供
10+
StampedLock lock = new StampedLock();
11+
long stamp = lock.tryOptimisticRead();
12+
Lock readLock = lock.asReadLock();
13+
try {
14+
readLock.lock();
15+
16+
lock.validate(stamp);
17+
} finally {
18+
readLock.unlock();
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)