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
24ea319
commit 0940276
Showing
12 changed files
with
317 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,5 @@ target/ | |
.DS_Store | ||
Thumbs.db | ||
*.orig | ||
|
||
.vs |
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 |
---|---|---|
|
@@ -28,5 +28,6 @@ | |
</build> | ||
<modules> | ||
<module>stage-4-lesson-1</module> | ||
<module>stage-4-lesson-2</module> | ||
</modules> | ||
</project> |
15 changes: 15 additions & 0 deletions
15
「一入 Java 深似海 」/代码/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/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-4</artifactId> | ||
<groupId>com.segmentfault</groupId> | ||
<version>1.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>stage-4-lesson-2</artifactId> | ||
<name>「一入 Java 深似海 」系列 :: 第四期 :: 第二节</name> | ||
|
||
</project> |
80 changes: 80 additions & 0 deletions
80
...c/main/java/com/segmentfault/deep/in/java/memory/model/HappensBeforeRelationshipDemo.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,80 @@ | ||
package com.segmentfault.deep.in.java.memory.model; | ||
|
||
/** | ||
* happens-before relationship | ||
*/ | ||
public class HappensBeforeRelationshipDemo { | ||
|
||
// 性能开销:Lock > CAS > volatile | ||
// 术语: Mutex > CAS > Memory Barrier | ||
// 底层分析:N多指令 > 多个指令 > 单个或若干指令 | ||
|
||
public static void main(String[] args) { | ||
|
||
} | ||
|
||
/** | ||
* If x and y are actions of the same thread and x comes before y in program order, | ||
* then hb(x, y). | ||
*/ | ||
private static void inSameThread() { | ||
// action1 | ||
// action2 | ||
} | ||
|
||
/** | ||
* There is a happens-before edge from the end of a constructor of an object to the | ||
* start of a finalizer (§12.6) for that object | ||
*/ | ||
private static void constructorHappensBeforeFinalizer() { | ||
// 构造早于销毁(终结)之前 | ||
// 构造对象是在用户线程(main、子线程)中执行 | ||
// Finalizer 操作是 JVM 线程(GC 线程)中执行 | ||
// 对象存放在 Heap 里面,Heap 对于线程是共享的 | ||
// 假设 Object 刚创建,Finalizer 线程看到该对象,马上回收 | ||
} | ||
|
||
/** | ||
* lock 对象是一个锁对象,也可视作 monitor | ||
*/ | ||
private static final Object monitor = new Object(); | ||
|
||
/** | ||
* The wait methods of class Object (§17.2.1) have lock and unlock actions | ||
* associated with them; their happens-before relationships are defined by these | ||
* associated actions. | ||
* | ||
* @throws InterruptedException | ||
*/ | ||
private static void synchronizedAndWait() throws InterruptedException { | ||
|
||
// JMM 描述: | ||
// monitor (lock) happens-before monitor.wait() | ||
// monitor.wait() happens-before monitor (unlock) | ||
|
||
// 实际情况: | ||
// monitor (lock) synchronizes-with monitor.wait() | ||
// monitor.wait() synchronizes-with monitor (unlock) | ||
|
||
// if x synchronizes-with y , then x happens-before y | ||
synchronized (monitor) { | ||
monitor.wait(); // | ||
// 当 wait() 方法所属对象没有被 synchronized 关键字修饰, | ||
// 将抛出 IllegalMonitorStateException | ||
} | ||
} | ||
|
||
private static void threadStartAndJoin() throws InterruptedException { | ||
|
||
Thread t = new Thread(() -> { | ||
// action 动作 | ||
}); | ||
|
||
t.start(); // start() 方法 happens-before actions 之前 | ||
|
||
// main 线程调用线程 t 的join() 方法 | ||
// 在 join() 方法返回之前,t 所有的 actions 已执行结束 | ||
t.join(); | ||
|
||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
...esson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/JavaMemoryModelDemo.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.memory.model; | ||
|
||
public class JavaMemoryModelDemo { | ||
|
||
/** | ||
* 广义同步:狭义锁(互斥)、volatile 以及原子操作(Unsafe) | ||
* Java9+ VarHandle | ||
*/ | ||
|
||
/** | ||
* 狭义锁(互斥): | ||
* OS 原语(Windows): | ||
* HANDLE mutex = CreateMutex(NULL, FALSE, NULL); | ||
* CRITICAL_SECTION critSec; | ||
* POSIX Thread 等高级 API: | ||
* pthread_mutex_t 数据结构 | ||
*/ | ||
|
||
/** | ||
* volatile | ||
* 确保: | ||
* 变量的可见性 | ||
* 引用的原子性:https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html | ||
* 实现: | ||
* 大部分利用 C++ volatile 编译时限制重排(内存屏障) | ||
* Memory Barriers:https://www.infoq.com/articles/memory_barriers_jvm_concurrency | ||
* 部分通过汇编实现 | ||
* 源码快速路径:orderAccess.hpp | ||
* | ||
*/ | ||
|
||
/** | ||
* 原子操作(Atomic) | ||
* 确保: | ||
* 变量的原子操作(自增长、exchange、CAS 等操作) | ||
* 实现: | ||
* 利用汇编指令 | ||
* 源码快速路径:atomic.hpp | ||
*/ | ||
} |
162 changes: 162 additions & 0 deletions
162
...rc/main/java/com/segmentfault/deep/in/java/memory/model/SynchronizedWithRelationDemo.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,162 @@ | ||
package com.segmentfault.deep.in.java.memory.model; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
/** | ||
* synchronized-with Relation | ||
*/ | ||
public class SynchronizedWithRelationDemo { | ||
|
||
private static final Object lock = new Object(); | ||
|
||
public static void main(String[] args) { | ||
|
||
} | ||
|
||
private static volatile int sharedData; | ||
|
||
/** | ||
* An unlock action on monitor m synchronizes-with all subsequent lock actions on | ||
* m (where "subsequent" is defined according to the synchronization order) | ||
* | ||
* @param data | ||
*/ | ||
private static void synchronizedChangeData(int data) { | ||
// T1 和 T2 两个线程 | ||
// T1 先获得锁 | ||
// T1 lock -> run() -> unlock | ||
// T2 被停顿(park) | ||
// T3 进入(停顿) | ||
// T1 unlock | ||
// T2 或 T3 获得锁机会 | ||
// T3 获得锁(T2 被停顿) | ||
// T3 lock -> unlock | ||
// 结果 | ||
// T1 unlock -> T3 lock | ||
synchronized (lock) { | ||
sharedData = data; | ||
} // unlock the monitor(lock) | ||
} | ||
|
||
|
||
/** | ||
* A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent | ||
* reads of v by any thread (where "subsequent" is defined according to the | ||
* synchronization order) | ||
* <p> | ||
* 假设 | ||
* T(w) :写线程 | ||
* T(r) : 读线程 | ||
* 且 T(w) 1 -> sharedData volatile 写 -> 0 => 1 | ||
* T(r) 1...n -> sharedData volatile 读 -> 0 => 1 | ||
*/ | ||
private static int getSharedData() { | ||
// volatile 读 | ||
// sharedData(1) | ||
return sharedData; | ||
} | ||
|
||
private static void volatileChangeDate(int data) { | ||
// volatile 写 | ||
// sharedData(0) -> 1 | ||
sharedData = data; | ||
|
||
// volatile 读 | ||
int tmpData = sharedData; | ||
} | ||
|
||
/** | ||
* An action that starts a thread synchronizes-with the first action in the thread it | ||
* starts. | ||
*/ | ||
private static void threadStart() { | ||
Thread thread = new Thread(() -> { | ||
}); | ||
|
||
thread.start(); // Thread.start() 方法必然在 Thread.run() 方法之前执行 | ||
} | ||
|
||
private static class Person { | ||
|
||
private final String name; | ||
|
||
private final int age; | ||
|
||
private final Collection<String> tags; | ||
|
||
// public Person() { | ||
// // name = null | ||
// // age = 0 | ||
// } | ||
|
||
/** | ||
* 线程在读取 Person 对象属性(name 或 age)时,线程不会读到字段在初始化的中间状态 | ||
* | ||
* @param name | ||
* @param age | ||
* @param tags | ||
*/ | ||
public Person(String name, int age, Collection<String> tags) { | ||
this.name = name; // String 是不变对象(引用) | ||
this.age = age; // age 是原生类型(复制) | ||
this.tags = tags; // Collection 是可变对象(引用) | ||
} | ||
|
||
} | ||
|
||
|
||
private static void initializeProperties() { | ||
|
||
/** | ||
* Person 对象初始化完成后,才能被其他线程访问对象属性 | ||
*/ | ||
List<String> tags = Arrays.asList("A", "B", "C"); | ||
/** | ||
* Java 方法参数特点 | ||
* 对于对象类型,引用 | ||
* 引用:普通对象、数组、集合(Collection、Map) | ||
* 对于原生类型,复制 | ||
*/ | ||
Person person = new Person("小马哥", 33, tags); | ||
|
||
/** | ||
* 修改第三个元素 "C" -> "E" | ||
*/ | ||
tags.set(2, "E"); | ||
|
||
Thread thread = new Thread(() -> { | ||
person.toString(); | ||
}); | ||
} | ||
|
||
|
||
private volatile boolean interrupted = false; | ||
|
||
private static void threadInterrupt() { | ||
|
||
Thread t2 = new Thread(() -> { | ||
if (Thread.interrupted()) { // volatile 读 t2 interrupt true and is cleared. | ||
// 会被执行 | ||
} | ||
}); | ||
|
||
Thread t1 = new Thread(() -> { | ||
// T1 调用 T2 interrupt() 方法 | ||
t2.interrupt(); // volatile 写 | ||
// t2 interrupt 状态 false -> true | ||
}); | ||
|
||
|
||
Thread t3 = new Thread(() -> { | ||
if (t2.isInterrupted()) { // volatile 读 t2 interrupt true | ||
// 会被执行 | ||
} | ||
}); | ||
|
||
// volatile 写 -> volatile 读 | ||
// t1 -> interrupt t2 -> t3,t4,t4 read isInterrupted() == true | ||
|
||
} | ||
} |
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
Binary file added
BIN
+375 KB
...期/第二节 Java 内存模型(Java Memory Model)/JSR-133 Java Memory Model and Thread Specification.pdf
Binary file not shown.
Binary file added
BIN
+406 KB
...第二节 Java 内存模型(Java Memory Model)/JavaOne 2004 - The New Java™ Technology Memory Model.pdf
Binary file not shown.
Binary file added
BIN
+3.19 MB
...期/第二节 Java 内存模型(Java Memory Model)/The Java Language Specification Java SE 12 Edition.pdf
Binary file not shown.
Binary file added
BIN
+2.47 MB
...节 Java 内存模型(Java Memory Model)/「一入 Java 深似海 」系列 第四期 第二节《Java 内存模型(Java Memory Model)》.pdf
Binary file not shown.
14 changes: 14 additions & 0 deletions
14
「一入 Java 深似海 」/第四期/第二节 Java 内存模型(Java Memory Model)/相关链接.txt
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,14 @@ | ||
Concurrency JSR-166 Interest Site | ||
http://g.oswego.edu/dl/concurrency-interest/ | ||
|
||
Memory Barriers and JVM Concurrency | ||
https://www.infoq.com/articles/memory_barriers_jvm_concurrency | ||
|
||
JSR | ||
https://github.com/mercyblitz/jsr | ||
|
||
Bill Pugh | ||
http://www.cs.umd.edu/~pugh/ | ||
|
||
Atomic Access | ||
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html |