Skip to content

Commit

Permalink
Add Stage 4 Lesson 2
Browse files Browse the repository at this point in the history
  • Loading branch information
mercyblitz committed Apr 14, 2019
1 parent 24ea319 commit 0940276
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ target/
.DS_Store
Thumbs.db
*.orig

.vs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@
</build>
<modules>
<module>stage-4-lesson-1</module>
<module>stage-4-lesson-2</module>
</modules>
</project>
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>
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();

}
}
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
*/
}
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

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\include;$(IncludePath)</IncludePath>
<LibraryPath>E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\dll\x86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
Expand Down Expand Up @@ -113,6 +115,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\lib\x86\pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
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

0 comments on commit 0940276

Please sign in to comment.