Skip to content

Commit 0940276

Browse files
committed
Add Stage 4 Lesson 2
1 parent 24ea319 commit 0940276

File tree

12 files changed

+317
-0
lines changed

12 files changed

+317
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ target/
2929
.DS_Store
3030
Thumbs.db
3131
*.orig
32+
33+
.vs

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@
2828
</build>
2929
<modules>
3030
<module>stage-4-lesson-1</module>
31+
<module>stage-4-lesson-2</module>
3132
</modules>
3233
</project>
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-4</artifactId>
7+
<groupId>com.segmentfault</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>stage-4-lesson-2</artifactId>
13+
<name>「一入 Java 深似海 」系列 :: 第四期 :: 第二节</name>
14+
15+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.segmentfault.deep.in.java.memory.model;
2+
3+
/**
4+
* happens-before relationship
5+
*/
6+
public class HappensBeforeRelationshipDemo {
7+
8+
// 性能开销:Lock > CAS > volatile
9+
// 术语: Mutex > CAS > Memory Barrier
10+
// 底层分析:N多指令 > 多个指令 > 单个或若干指令
11+
12+
public static void main(String[] args) {
13+
14+
}
15+
16+
/**
17+
* If x and y are actions of the same thread and x comes before y in program order,
18+
* then hb(x, y).
19+
*/
20+
private static void inSameThread() {
21+
// action1
22+
// action2
23+
}
24+
25+
/**
26+
* There is a happens-before edge from the end of a constructor of an object to the
27+
* start of a finalizer (§12.6) for that object
28+
*/
29+
private static void constructorHappensBeforeFinalizer() {
30+
// 构造早于销毁(终结)之前
31+
// 构造对象是在用户线程(main、子线程)中执行
32+
// Finalizer 操作是 JVM 线程(GC 线程)中执行
33+
// 对象存放在 Heap 里面,Heap 对于线程是共享的
34+
// 假设 Object 刚创建,Finalizer 线程看到该对象,马上回收
35+
}
36+
37+
/**
38+
* lock 对象是一个锁对象,也可视作 monitor
39+
*/
40+
private static final Object monitor = new Object();
41+
42+
/**
43+
* The wait methods of class Object (§17.2.1) have lock and unlock actions
44+
* associated with them; their happens-before relationships are defined by these
45+
* associated actions.
46+
*
47+
* @throws InterruptedException
48+
*/
49+
private static void synchronizedAndWait() throws InterruptedException {
50+
51+
// JMM 描述:
52+
// monitor (lock) happens-before monitor.wait()
53+
// monitor.wait() happens-before monitor (unlock)
54+
55+
// 实际情况:
56+
// monitor (lock) synchronizes-with monitor.wait()
57+
// monitor.wait() synchronizes-with monitor (unlock)
58+
59+
// if x synchronizes-with y , then x happens-before y
60+
synchronized (monitor) {
61+
monitor.wait(); //
62+
// 当 wait() 方法所属对象没有被 synchronized 关键字修饰,
63+
// 将抛出 IllegalMonitorStateException
64+
}
65+
}
66+
67+
private static void threadStartAndJoin() throws InterruptedException {
68+
69+
Thread t = new Thread(() -> {
70+
// action 动作
71+
});
72+
73+
t.start(); // start() 方法 happens-before actions 之前
74+
75+
// main 线程调用线程 t 的join() 方法
76+
// 在 join() 方法返回之前,t 所有的 actions 已执行结束
77+
t.join();
78+
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.segmentfault.deep.in.java.memory.model;
2+
3+
public class JavaMemoryModelDemo {
4+
5+
/**
6+
* 广义同步:狭义锁(互斥)、volatile 以及原子操作(Unsafe)
7+
* Java9+ VarHandle
8+
*/
9+
10+
/**
11+
* 狭义锁(互斥):
12+
* OS 原语(Windows):
13+
* HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
14+
* CRITICAL_SECTION critSec;
15+
* POSIX Thread 等高级 API:
16+
* pthread_mutex_t 数据结构
17+
*/
18+
19+
/**
20+
* volatile
21+
* 确保:
22+
* 变量的可见性
23+
* 引用的原子性:https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
24+
* 实现:
25+
* 大部分利用 C++ volatile 编译时限制重排(内存屏障)
26+
* Memory Barriers:https://www.infoq.com/articles/memory_barriers_jvm_concurrency
27+
* 部分通过汇编实现
28+
* 源码快速路径:orderAccess.hpp
29+
*
30+
*/
31+
32+
/**
33+
* 原子操作(Atomic)
34+
* 确保:
35+
* 变量的原子操作(自增长、exchange、CAS 等操作)
36+
* 实现:
37+
* 利用汇编指令
38+
* 源码快速路径:atomic.hpp
39+
*/
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package com.segmentfault.deep.in.java.memory.model;
2+
3+
import java.util.Arrays;
4+
import java.util.Collection;
5+
import java.util.List;
6+
7+
/**
8+
* synchronized-with Relation
9+
*/
10+
public class SynchronizedWithRelationDemo {
11+
12+
private static final Object lock = new Object();
13+
14+
public static void main(String[] args) {
15+
16+
}
17+
18+
private static volatile int sharedData;
19+
20+
/**
21+
* An unlock action on monitor m synchronizes-with all subsequent lock actions on
22+
* m (where "subsequent" is defined according to the synchronization order)
23+
*
24+
* @param data
25+
*/
26+
private static void synchronizedChangeData(int data) {
27+
// T1 和 T2 两个线程
28+
// T1 先获得锁
29+
// T1 lock -> run() -> unlock
30+
// T2 被停顿(park)
31+
// T3 进入(停顿)
32+
// T1 unlock
33+
// T2 或 T3 获得锁机会
34+
// T3 获得锁(T2 被停顿)
35+
// T3 lock -> unlock
36+
// 结果
37+
// T1 unlock -> T3 lock
38+
synchronized (lock) {
39+
sharedData = data;
40+
} // unlock the monitor(lock)
41+
}
42+
43+
44+
/**
45+
* A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent
46+
* reads of v by any thread (where "subsequent" is defined according to the
47+
* synchronization order)
48+
* <p>
49+
* 假设
50+
* T(w) :写线程
51+
* T(r) : 读线程
52+
* 且 T(w) 1 -> sharedData volatile 写 -> 0 => 1
53+
* T(r) 1...n -> sharedData volatile 读 -> 0 => 1
54+
*/
55+
private static int getSharedData() {
56+
// volatile 读
57+
// sharedData(1)
58+
return sharedData;
59+
}
60+
61+
private static void volatileChangeDate(int data) {
62+
// volatile 写
63+
// sharedData(0) -> 1
64+
sharedData = data;
65+
66+
// volatile 读
67+
int tmpData = sharedData;
68+
}
69+
70+
/**
71+
* An action that starts a thread synchronizes-with the first action in the thread it
72+
* starts.
73+
*/
74+
private static void threadStart() {
75+
Thread thread = new Thread(() -> {
76+
});
77+
78+
thread.start(); // Thread.start() 方法必然在 Thread.run() 方法之前执行
79+
}
80+
81+
private static class Person {
82+
83+
private final String name;
84+
85+
private final int age;
86+
87+
private final Collection<String> tags;
88+
89+
// public Person() {
90+
// // name = null
91+
// // age = 0
92+
// }
93+
94+
/**
95+
* 线程在读取 Person 对象属性(name 或 age)时,线程不会读到字段在初始化的中间状态
96+
*
97+
* @param name
98+
* @param age
99+
* @param tags
100+
*/
101+
public Person(String name, int age, Collection<String> tags) {
102+
this.name = name; // String 是不变对象(引用)
103+
this.age = age; // age 是原生类型(复制)
104+
this.tags = tags; // Collection 是可变对象(引用)
105+
}
106+
107+
}
108+
109+
110+
private static void initializeProperties() {
111+
112+
/**
113+
* Person 对象初始化完成后,才能被其他线程访问对象属性
114+
*/
115+
List<String> tags = Arrays.asList("A", "B", "C");
116+
/**
117+
* Java 方法参数特点
118+
* 对于对象类型,引用
119+
* 引用:普通对象、数组、集合(Collection、Map)
120+
* 对于原生类型,复制
121+
*/
122+
Person person = new Person("小马哥", 33, tags);
123+
124+
/**
125+
* 修改第三个元素 "C" -> "E"
126+
*/
127+
tags.set(2, "E");
128+
129+
Thread thread = new Thread(() -> {
130+
person.toString();
131+
});
132+
}
133+
134+
135+
private volatile boolean interrupted = false;
136+
137+
private static void threadInterrupt() {
138+
139+
Thread t2 = new Thread(() -> {
140+
if (Thread.interrupted()) { // volatile 读 t2 interrupt true and is cleared.
141+
// 会被执行
142+
}
143+
});
144+
145+
Thread t1 = new Thread(() -> {
146+
// T1 调用 T2 interrupt() 方法
147+
t2.interrupt(); // volatile 写
148+
// t2 interrupt 状态 false -> true
149+
});
150+
151+
152+
Thread t3 = new Thread(() -> {
153+
if (t2.isInterrupted()) { // volatile 读 t2 interrupt true
154+
// 会被执行
155+
}
156+
});
157+
158+
// volatile 写 -> volatile 读
159+
// t1 -> interrupt t2 -> t3,t4,t4 read isInterrupted() == true
160+
161+
}
162+
}

「一入 Java 深似海 」/代码/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
</PropertyGroup>
7878
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
7979
<LinkIncremental>true</LinkIncremental>
80+
<IncludePath>E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\include;$(IncludePath)</IncludePath>
81+
<LibraryPath>E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\dll\x86;$(LibraryPath)</LibraryPath>
8082
</PropertyGroup>
8183
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
8284
<LinkIncremental>false</LinkIncremental>
@@ -113,6 +115,7 @@
113115
<Link>
114116
<SubSystem>Console</SubSystem>
115117
<GenerateDebugInformation>true</GenerateDebugInformation>
118+
<AdditionalDependencies>E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\lib\x86\pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
116119
</Link>
117120
</ItemDefinitionGroup>
118121
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

0 commit comments

Comments
 (0)