forked from mercyblitz/segmentfault-lessons
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c42bf5f
commit 4cab64e
Showing
12 changed files
with
357 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
「一入 Java 深似海 」/代码/segmentfault/deep-in-java/stage-3/stage-3-lesson-3/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>stage-3</artifactId> | ||
<groupId>com.segmentfault</groupId> | ||
<version>1.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>stage-3-lesson-3</artifactId> | ||
<name>「一入 Java 深似海 」系列 :: 第三期 :: 第三节</name> | ||
|
||
</project> |
22 changes: 22 additions & 0 deletions
22
...sson-3/src/main/java/com/segmentfault/deep/in/java/concurrency/AcquireAndReleaseDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
public class AcquireAndReleaseDemo { | ||
|
||
public static void main(String[] args) { | ||
// Lock 机制 | ||
// 获得 Acquire | ||
// Thread 进入 synchronized -> 获得锁 | ||
// 释放 Release | ||
// 1. 当 Thread(hold lock),调用 Object#wait() 时候 | ||
// 2. Thread park -> LockSupport.park(Object) | ||
// 3. Condition#await() | ||
// 4. 运行期异常,Thread 消亡 | ||
// 5. Java 9 自旋 Thread.onSpinWait(); | ||
// 6. Thread.yield(); | ||
|
||
// 所谓的公平(Fair)和非公平(Nonfair、unfair) | ||
// 公平(Fair)线程 FIFO | ||
// 非公平(Nonfair)线程随线程调度 | ||
// 最佳实践:在创建线程时,除非必要,不要调整线程优先级(Priority) | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
.../stage-3-lesson-3/src/main/java/com/segmentfault/deep/in/java/concurrency/AtomicDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
import sun.misc.Unsafe; | ||
|
||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.VarHandle; | ||
import java.lang.reflect.Field; | ||
import java.security.AccessController; | ||
import java.security.PrivilegedActionException; | ||
import java.security.PrivilegedExceptionAction; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
|
||
public class AtomicDemo { | ||
|
||
public static void main(String[] args) throws Exception { | ||
// CAS 是一种相对(MB)较重的比较,轻量级的锁(标量) | ||
|
||
getUnsafe(); | ||
|
||
// volatile 修饰复杂对象类型时,不具备被传递到字段安全 | ||
} | ||
|
||
private static void demoAtomicLong() { | ||
// long 表示 64位(8字节),高和低两端 | ||
// long 并非线程安全,就是 volatile(高和低操作时,至少两次操作) | ||
AtomicLong l = new AtomicLong(); | ||
// set 和 get 通过 JVM 特殊操作,不在直接写入和获取 | ||
} | ||
|
||
private static void demoAtomicInteger() { | ||
// int 表示 int(32), char(16), short(16), byte(8), boolean(1) | ||
// AtomicInteger 内部使用 int 作为变量标识,1 表示 true, 0 表示 false | ||
// AtomicInteger set 和 get 操作均为 volatile 语义(MB) | ||
// AtomicInteger CAS Unsafe(Java 8) 和 VarHandle(Java 9+) | ||
} | ||
|
||
private static void demoAtomicBoolean() { | ||
AtomicBoolean b = new AtomicBoolean(); | ||
// AtomicBoolean 内部使用 int 作为变量标识,1 表示 true, 0 表示 false | ||
// AtomicBoolean set 和 get 操作均为 volatile 语义(MB) | ||
// AtomicBoolean CAS Unsafe(Java 8) 和 VarHandle(Java 9+) | ||
} | ||
|
||
private static void getVarHandle() { | ||
MethodHandles.Lookup l = MethodHandles.lookup(); | ||
} | ||
|
||
private static void getUnsafe() throws PrivilegedActionException { | ||
// 无法通过正常方法调用 | ||
// Unsafe unsafe = Unsafe.getUnsafe(); | ||
|
||
// https://github.com/mercyblitz/confucius-commons/blob/master/confucius-commons-lang/src/main/java/org/confucius/commons/lang/misc/UnsafeUtils.java | ||
final PrivilegedExceptionAction<Unsafe> action = new PrivilegedExceptionAction<Unsafe>() { | ||
public Unsafe run() throws Exception { | ||
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); | ||
theUnsafe.setAccessible(true); | ||
return (Unsafe) theUnsafe.get(null); | ||
} | ||
}; | ||
|
||
Unsafe unsafe = AccessController.doPrivileged(action); | ||
|
||
if (unsafe == null) { | ||
throw new NullPointerException(); | ||
} | ||
|
||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
...-lesson-3/src/main/java/com/segmentfault/deep/in/java/concurrency/CountDownLatchDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
import java.util.concurrent.CountDownLatch; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
public class CountDownLatchDemo { | ||
|
||
public static void main(String[] args) throws InterruptedException { | ||
// 4 -> 3 -> 2 -> 1 | ||
CountDownLatch latch = new CountDownLatch(4); // 4 个计数 | ||
ExecutorService executorService = Executors.newFixedThreadPool(3); // 线程数 3 | ||
|
||
for (int i = 0; i < 3; i++) { // 启动3个线程 | ||
executorService.submit(() -> { | ||
try { | ||
echoThread(); | ||
latch.countDown(); // -1 | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
}); | ||
} | ||
|
||
Thread.sleep(5 * 100); | ||
|
||
// 当 count 数量等于 0,才会释放 | ||
// 4-3 == 1 !=0 | ||
System.out.println("CountDownLatch 剩余数量:" + latch.getCount()); | ||
latch.await(); // await 类似 wait() -> join | ||
|
||
// 关闭线程池 | ||
executorService.shutdown(); | ||
|
||
} | ||
|
||
private static void echoThread() { | ||
System.out.printf("当前线程[%s]正在执行...\n", Thread.currentThread().getName()); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
...3-lesson-3/src/main/java/com/segmentfault/deep/in/java/concurrency/CyclicBarrierDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
import java.util.concurrent.BrokenBarrierException; | ||
import java.util.concurrent.CyclicBarrier; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
public class CyclicBarrierDemo { | ||
|
||
public static void main(String[] args) throws BrokenBarrierException, InterruptedException { | ||
|
||
CyclicBarrier cb = new CyclicBarrier(4); | ||
|
||
ExecutorService executorService = Executors.newFixedThreadPool(3); | ||
|
||
for (int i = 0; i < 3; i++) { | ||
executorService.submit(() -> { | ||
try { | ||
echoThread(); | ||
cb.await(); // await() 让计数 -1 | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
}); | ||
} | ||
|
||
Thread.sleep(5 * 100); | ||
|
||
// 当 count 数量等于 0,才会释放 | ||
// 4 - 3 == 1 !=0 | ||
// 再次 await() -1 => 4 - 3 - 1 = 0 | ||
System.out.println(cb.getNumberWaiting()); | ||
cb.await(); | ||
System.out.println(cb.getNumberWaiting()); | ||
|
||
// // reset() 操作是恢复计数 0 -> 4 | ||
cb.reset(); | ||
System.out.println(cb.getNumberWaiting()); | ||
// | ||
// 关闭线程池 | ||
executorService.shutdown(); | ||
|
||
} | ||
|
||
|
||
private static void echoThread() { | ||
System.out.printf("当前线程[%s]正在执行...\n", Thread.currentThread().getName()); | ||
} | ||
|
||
} |
81 changes: 81 additions & 0 deletions
81
...3-lesson-3/src/main/java/com/segmentfault/deep/in/java/concurrency/ReentrantLockDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.locks.Condition; | ||
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.ReentrantLock; | ||
|
||
public class ReentrantLockDemo { | ||
|
||
public static void main(String[] args) { | ||
lockOpsMethods(); | ||
} | ||
|
||
private static void lockOpsMethods() { | ||
ReentrantLock lock = new ReentrantLock(); | ||
int count = lock.getHoldCount(); | ||
System.out.printf("在 lock() 方法调用之前的线程[%s]重进入数:%d\n", Thread.currentThread().getName(), count); | ||
lock(lock, 100); | ||
} | ||
|
||
private static void lock(ReentrantLock lock, int times) { | ||
|
||
if (times < 1) { | ||
return; | ||
} | ||
|
||
lock.lock(); | ||
|
||
try { | ||
// times-- load, minus 1 | ||
lock(lock, --times); | ||
System.out.printf("第%s次在 lock() 方法调用之后的线程[%s]重进入数:%d\n", | ||
times+1, | ||
Thread.currentThread().getName(), | ||
lock.getHoldCount()); | ||
} finally { | ||
lock.unlock(); | ||
} | ||
|
||
} | ||
|
||
private static void conditionObject() { | ||
Lock lock = new ReentrantLock(); | ||
// 条件变量包括条件,同时它又是线程通讯媒介 | ||
Condition condition = lock.newCondition(); | ||
try { | ||
condition.await(); | ||
} catch (InterruptedException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
private static void tryLockInTimeout() { | ||
Lock lock = new ReentrantLock(); | ||
|
||
try { | ||
if (lock.tryLock(3, TimeUnit.SECONDS)) { // 当前仅当在规定的时间内获得锁 | ||
// Lock API 语义补充了 synchronized 原语的不足 | ||
// TODO Add some logic | ||
} | ||
} catch (InterruptedException e) { | ||
// 重置中止状态(防止被中途清除 interrupt 状态) | ||
Thread.currentThread().interrupt(); | ||
// logger error message | ||
} | ||
} | ||
|
||
private static void synchronizedStatement() { | ||
// 假设出现死锁或者饥饿 | ||
synchronized (ReentrantLockDemo.class) { | ||
|
||
if (3 > 2) { // 条件 | ||
try { | ||
ReentrantLockDemo.class.wait(); // Object 线程通讯方法 | ||
} catch (InterruptedException e) { | ||
// logger error message | ||
} | ||
} | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...3/src/main/java/com/segmentfault/deep/in/java/concurrency/ReentrantReadWriteLockDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.ReadWriteLock; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
|
||
public class ReentrantReadWriteLockDemo { | ||
|
||
public static void main(String[] args) { | ||
|
||
ReadWriteLock lock = new ReentrantReadWriteLock(); | ||
|
||
Lock readLock = lock.readLock(); | ||
|
||
Lock writeLock = lock.writeLock(); | ||
|
||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
...age-3-lesson-3/src/main/java/com/segmentfault/deep/in/java/concurrency/SemaphoreDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
import java.util.concurrent.*; | ||
|
||
public class SemaphoreDemo { | ||
|
||
public static void main(String[] args) throws BrokenBarrierException, InterruptedException { | ||
|
||
Semaphore cb = new Semaphore(4); | ||
|
||
ExecutorService executorService = Executors.newFixedThreadPool(3); | ||
|
||
for (int i = 0; i < 3; i++) { | ||
executorService.submit(() -> { | ||
try { | ||
echoThread(); | ||
cb.acquire(); // await() 让计数 -1 | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
}); | ||
} | ||
|
||
Thread.sleep(5 * 100); | ||
|
||
// 当 count 数量等于 0,才会释放 | ||
// 4 - 3 == 1 !=0 | ||
// 再次 await() -1 => 4 - 3 - 1 = 0 | ||
// | ||
// 关闭线程池 | ||
executorService.shutdown(); | ||
|
||
} | ||
|
||
|
||
private static void echoThread() { | ||
System.out.printf("当前线程[%s]正在执行...\n", Thread.currentThread().getName()); | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
...e-3-lesson-3/src/main/java/com/segmentfault/deep/in/java/concurrency/StampedLockDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.segmentfault.deep.in.java.concurrency; | ||
|
||
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.StampedLock; | ||
|
||
public class StampedLockDemo { | ||
|
||
public static void main(String[] args) { | ||
// Java 1.8 之后提供 | ||
StampedLock lock = new StampedLock(); | ||
long stamp = lock.tryOptimisticRead(); | ||
Lock readLock = lock.asReadLock(); | ||
try { | ||
readLock.lock(); | ||
|
||
lock.validate(stamp); | ||
} finally { | ||
readLock.unlock(); | ||
} | ||
} | ||
} |
Binary file added
BIN
+2.15 MB
「一入 Java 深似海 」/第三期/第三节 Java 并发框架基础运用/Multithreading-and-Concurrency-Questions.pdf
Binary file not shown.
Binary file added
BIN
+4.34 MB
「一入 Java 深似海 」/第三期/第三节 Java 并发框架基础运用/「一入 Java 深似海 」系列 第三期 第三节 《Java 并发框架基础运用》.pdf
Binary file not shown.