Skip to content

Commit

Permalink
Add Stage 3 Lesson 3
Browse files Browse the repository at this point in the history
  • Loading branch information
mercyblitz committed Mar 24, 2019
1 parent c42bf5f commit 4cab64e
Show file tree
Hide file tree
Showing 12 changed files with 357 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<modules>
<module>stage-3-lesson-1</module>
<module>stage-3-lesson-2</module>
<module>stage-3-lesson-3</module>
</modules>
<packaging>pom</packaging>

Expand Down
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>
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)
}
}
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();
}

}
}
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());
}
}
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());
}

}
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
}
}
}
}
}
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();

}
}
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());
}

}
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 not shown.

0 comments on commit 4cab64e

Please sign in to comment.