aQueue = new ArrayBlockingQueue<>(1);
+
+ aQueue.add(1);
+
+ System.out.println(aQueue.size());
+
+ }
+
+ // offer 方法来自于 Queue 接口,因此,子接口无法超越 Queue 方法签名
+
+ public boolean equals(Object object)
+// throws Exception // 错误(编译时):超越父类 Object equals(Object) 方法签名
+ throws RuntimeException // 非 checked 异常时没有以上限制
+ {
+
+ return false;
+ }
+}
+
+
+
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/pom.xml"
new file mode 100644
index 0000000..e092352
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/pom.xml"
@@ -0,0 +1,34 @@
+
+
+
+ deep-in-java
+ com.segmentfault
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ stage-4
+ pom
+ 「一入 Java 深似海 」系列 :: 第四期
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+ 11
+ 11
+
+
+
+
+
+ stage-4-lesson-1
+ stage-4-lesson-2
+ stage-4-lesson-3
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/pom.xml"
new file mode 100644
index 0000000..03659c0
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/pom.xml"
@@ -0,0 +1,16 @@
+
+
+
+ stage-4
+ com.segmentfault
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ stage-4-lesson-1
+ 「一入 Java 深似海 」系列 :: 第四期 :: 第一节
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/src/main/java/com/segmentfault/deep/in/java/concurrency/HelloWorldThreadDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/src/main/java/com/segmentfault/deep/in/java/concurrency/HelloWorldThreadDemo.java"
new file mode 100644
index 0000000..6e19324
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/src/main/java/com/segmentfault/deep/in/java/concurrency/HelloWorldThreadDemo.java"
@@ -0,0 +1,24 @@
+package com.segmentfault.deep.in.java.concurrency;
+
+public class HelloWorldThreadDemo {
+
+ public static void main(String[] args) throws Exception {
+
+ // 创建 Java 线程
+ // Java 线程对象和 JVM OS 线程并不是同一对象
+ Thread t1 = new Thread(HelloWorldThreadDemo::helloWorld);
+ // 主线程 main 显示地启动子线程
+ t1.start(); // pthread_create()
+
+ // 等待线程执行结束
+ t1.join(); // pthread_join()
+
+ // 当线程 isAlive() 返回 false 时,JVM 线程已经消亡了(delete this)
+ System.out.printf("线程状态 : %s , 是否存活 : %s", t1.getState(), t1.isAlive());
+ }
+
+ static void helloWorld() {
+ System.out.printf("Thread[id : %d] - Hello World\n",
+ Thread.currentThread().getId());
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/src/main/java/com/segmentfault/deep/in/java/concurrency/SynchronizationDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/src/main/java/com/segmentfault/deep/in/java/concurrency/SynchronizationDemo.java"
new file mode 100644
index 0000000..91cece8
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-1/src/main/java/com/segmentfault/deep/in/java/concurrency/SynchronizationDemo.java"
@@ -0,0 +1,50 @@
+package com.segmentfault.deep.in.java.concurrency;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class SynchronizationDemo {
+
+ // pthread_mutex_t lock;
+ static Lock lock = new ReentrantLock();
+
+ static volatile int counter = 0;
+
+ public static void main(String[] args) throws Exception {
+
+ // pthread_cond_t condition1;
+ Condition condition1 = lock.newCondition();
+
+ // 前提:Lock#lock()
+ // await() 和 signal() 或 signalAll()
+
+ // 前提:synchronized(object) ->
+ // Object wait() 和 notify() 或 notifyAll();
+
+ synchronized (Object.class) {
+// Object.class.wait();
+ }
+
+ Thread t1 = new Thread(SynchronizationDemo::addCounter);
+ Thread t2 = new Thread(SynchronizationDemo::addCounter);
+ t1.start();
+ t2.start();
+
+ t1.join();
+ t2.join();
+ }
+
+ private static void addCounter() {
+ lock.lock(); // pthread_mutex_lock()
+ // lock.tryLock() // pthread_mutex_trylock()
+ System.out.println(getThreadPrefix() + "Before Counter : " + counter);
+ counter++;
+ System.out.println(getThreadPrefix() + "After Counter : " + counter);
+ lock.unlock(); // pthread_mutex_unlock()
+ }
+
+ private static String getThreadPrefix() {
+ return "Thread[" + Thread.currentThread().getId() + "] : ";
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/pom.xml"
new file mode 100644
index 0000000..3d80846
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/pom.xml"
@@ -0,0 +1,15 @@
+
+
+
+ stage-4
+ com.segmentfault
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ stage-4-lesson-2
+ 「一入 Java 深似海 」系列 :: 第四期 :: 第二节
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/HappensBeforeRelationshipDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/HappensBeforeRelationshipDemo.java"
new file mode 100644
index 0000000..cc9d563
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/HappensBeforeRelationshipDemo.java"
@@ -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();
+
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/JavaMemoryModelDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/JavaMemoryModelDemo.java"
new file mode 100644
index 0000000..7c9057c
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/JavaMemoryModelDemo.java"
@@ -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
+ */
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/SynchronizedWithRelationDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/SynchronizedWithRelationDemo.java"
new file mode 100644
index 0000000..21d116a
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-2/src/main/java/com/segmentfault/deep/in/java/memory/model/SynchronizedWithRelationDemo.java"
@@ -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)
+ *
+ * 假设
+ * 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 tags;
+
+// public Person() {
+// // name = null
+// // age = 0
+// }
+
+ /**
+ * 线程在读取 Person 对象属性(name 或 age)时,线程不会读到字段在初始化的中间状态
+ *
+ * @param name
+ * @param age
+ * @param tags
+ */
+ public Person(String name, int age, Collection tags) {
+ this.name = name; // String 是不变对象(引用)
+ this.age = age; // age 是原生类型(复制)
+ this.tags = tags; // Collection 是可变对象(引用)
+ }
+
+ }
+
+
+ private static void initializeProperties() {
+
+ /**
+ * Person 对象初始化完成后,才能被其他线程访问对象属性
+ */
+ List 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
+
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-3/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-3/pom.xml"
new file mode 100644
index 0000000..89fb545
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-3/pom.xml"
@@ -0,0 +1,15 @@
+
+
+
+ stage-4
+ com.segmentfault
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ stage-4-lesson-3
+ 「一入 Java 深似海 」系列 :: 第四期 :: 第三节
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-3/src/main/java/com/segmentfault/deep/in/java/aqs/AbstractQueuedSynchronizerDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-3/src/main/java/com/segmentfault/deep/in/java/aqs/AbstractQueuedSynchronizerDemo.java"
new file mode 100644
index 0000000..3a27d99
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-4/stage-4-lesson-3/src/main/java/com/segmentfault/deep/in/java/aqs/AbstractQueuedSynchronizerDemo.java"
@@ -0,0 +1,78 @@
+package com.segmentfault.deep.in.java.aqs;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+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 AbstractQueuedSynchronizerDemo {
+
+ // ReentrantLock is AbstractQueuedSynchronizer
+ private static Lock lock = new ReentrantLock();
+
+ // Condition is a part of ReentrantLock or AbstractQueuedSynchronizer
+ private static Condition condition = lock.newCondition();
+
+ public static void main(String[] args) throws InterruptedException {
+
+ ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+ // 一个线程获得锁,另外一个线程入队
+
+ // main -> thread-2.interrupt()
+ // sub-threads
+ List threads = new ArrayList<>();
+
+ executorService.submit(() -> {
+ threads.add(Thread.currentThread());
+ action();
+
+ }); // thread-1
+ executorService.submit(AbstractQueuedSynchronizerDemo::action); // thread-1
+ executorService.submit(AbstractQueuedSynchronizerDemo::action); // thread-2
+ executorService.submit(AbstractQueuedSynchronizerDemo::action); // thread-3
+
+
+ // 非公平锁
+ // thread-1 unlock -> release -> unpark thread-2 -> thread-2 try acquire
+ // thread-4 or thread-5 lock -> try acquire
+
+ // PS : unpark = LockSupport.unpark
+
+ // 公平锁
+ // thread-1 unlock -> release -> unpark thread-2 -> thread-2 try acquire
+ // thread-2 lock -> ..
+ // thread-3 wait
+ // thread-4 wait
+ // thread-5 wait
+
+ // 等待 200 秒
+ executorService.awaitTermination(200, TimeUnit.SECONDS);
+ // 关闭线程池
+ executorService.shutdown();
+
+ }
+
+ private static void action() {
+ System.out.printf("当前线程[%s] 正在等待您的输入\n", Thread.currentThread().getName());
+ // I/O 中断线程
+ try {
+
+
+ // 利用 ReentrantLock 作为 AQS 实现,理解内部数据结构
+ lock.lock();
+ System.in.read();
+ System.out.printf("当前线程[%s] 执行结束...\n", Thread.currentThread().getName());
+ } catch (IOException e) {
+ throw new RuntimeException();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/pom.xml"
new file mode 100644
index 0000000..5354e13
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/pom.xml"
@@ -0,0 +1,19 @@
+
+
+
+ deep-in-java
+ com.segmentfault
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ stage-5
+ pom
+ 「一入 Java 深似海 」系列 :: 第五期
+
+ stage-5-lesson-1
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/pom.xml"
new file mode 100644
index 0000000..fff295f
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/pom.xml"
@@ -0,0 +1,26 @@
+
+
+
+ stage-5
+ com.segmentfault
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ stage-5-lesson-1
+ 「一入 Java 深似海 」系列 :: 第五期 :: 第一节
+
+
+
+
+
+ commons-io
+ commons-io
+ 2.6
+
+
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassAndClassLoaderDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassAndClassLoaderDemo.java"
new file mode 100644
index 0000000..57354fd
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassAndClassLoaderDemo.java"
@@ -0,0 +1,30 @@
+package com.segmentfault.deep.in.java;
+
+/**
+ * Class 与 ClassLoader 之间的关系
+ */
+public class ClassAndClassLoaderDemo {
+
+ public static void main(String[] args) {
+
+ // 获取加载 Object.class 的 ClassLoader
+ // Object 是被 Bootstrap ClassLoader 加载,其 Java 表现形式为 null
+ getClassLoader(Object.class);
+ // 获取加载原生类型 int 的 ClassLoader
+ // int.class 是被 Bootstrap ClassLoader 加载,其 Java 表现形式为 null
+ getClassLoader(int.class);
+
+ // 当前 ClassAndClassLoaderDemo?
+ getClassLoader(ClassAndClassLoaderDemo.class);
+ // 加载 ClassAndClassLoaderDemo.class 的 ClassLoader
+ // 是否与系统 ClassLoader 相同
+ System.out.println(ClassAndClassLoaderDemo.class.getClassLoader()
+ == ClassLoader.getSystemClassLoader());
+
+ }
+
+ private static void getClassLoader(Class klass) {
+ System.out.printf("当前类[%s] 被 %s ClassLoader 加载\n", klass,
+ klass.getClassLoader());
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoaderAndClassPathDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoaderAndClassPathDemo.java"
new file mode 100644
index 0000000..0aa974d
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoaderAndClassPathDemo.java"
@@ -0,0 +1,30 @@
+package com.segmentfault.deep.in.java;
+
+/**
+ * ClassLoader 与 ClassPath 之间的关系示例代码
+ */
+public class ClassLoaderAndClassPathDemo {
+
+
+ public static void main(String[] args) {
+ // 通常,在 JVM 进程中添加 -verbose:class 参数来显示加载的 Class
+ // 所在的位置(source),如:
+ // [0.397s][info][class,load] com.segmentfault.deep.in.java.ClassLoaderAndClassPathDemo source: file:/E:/workspace/github/mercyblitz/segmentfault-lessons/%e3%80%8c%e4%b8%80%e5%85%a5%20Java%20%e6%b7%b1%e4%bc%bc%e6%b5%b7%20%e3%80%8d/%e4%bb%a3%e7%a0%81/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/target/classes/
+ // Bootstrap ClassLoader 加载的 Class 将会抛出 java.lang.NullPointerException
+// getClassLocation(Object.class);
+// getClassLocation(int.class);
+ // 类资源与 URL 有关联,是否意味着 ClassLoader 与 URL 存在关联
+ getClassLocation(ClassLoaderAndClassPathDemo.class);
+ // Spring Boot spring-boot-loader
+ // 文件目录:Expose -> File Handler
+ // 文件:JAR、WAR、EAR Jar Handler
+ // URL 抽象 Java 资源管理
+
+
+ }
+
+ private static void getClassLocation(Class> klass) {
+ System.out.printf("类[%s] 资源所在的位置:%s\n", klass,
+ klass.getProtectionDomain().getCodeSource().getLocation());
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoaderDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoaderDemo.java"
new file mode 100644
index 0000000..468b6ef
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoaderDemo.java"
@@ -0,0 +1,67 @@
+package com.segmentfault.deep.in.java;
+
+import java.util.ServiceLoader;
+
+/**
+ * ClassLoader 示例代码
+ */
+public class ClassLoaderDemo {
+
+ public static void main(String[] args) {
+ // 系统 ClassLoader
+ // Java 8 结果:sun.misc.Launcher$AppClassLoader@18b4aac2
+ // Java 12 结果:jdk.internal.loader.ClassLoaders$AppClassLoader@3fee733d
+ System.out.println(ClassLoader.getSystemClassLoader()); // 只读
+ // 应用 ClassLoader
+ // Java 8 结果:sun.misc.Launcher$AppClassLoader@18b4aac2
+ // Java 12 结果:jdk.internal.loader.ClassLoaders$AppClassLoader@3fee733d
+ System.out.println(Thread.currentThread().getContextClassLoader()); // 可修改
+
+ // 如何实现类隔离,通过修改 Thread 上下文 ClassLoader
+
+
+ // ClassLoader previousClassLoader = Thread.currentThread().getContextLoader();
+ // previousClassLoader 能够加载 User.class V1 版本(user-api-1.0.0.jar 文件中,在 /classpath1 目录下)
+ // User.class V2 版本 (user-api-2.0.0.jar 文件中,在 /classpath2 目录下)
+ // loadUser 操作加载 User.class V2 版本
+
+ // previousClassLoader ClassPath -> /classpath1
+ // newClassLoader ClassPath -> /classpath2
+
+ // 通常,系统或者应用(包括自定义) ClassLoader 均为 URLClassLoader 子类
+ }
+
+ private static void changeClassLoader(ClassLoader newClassLoader) {
+ Thread currentThread = Thread.currentThread();
+ // 当前 ClassLoader 无法加载 User.class 类,不过该类能被 newClassLoader 加载
+ ClassLoader previousClassLoader = currentThread.getContextClassLoader();
+ try {
+ currentThread.setContextClassLoader(newClassLoader); // 需要 setContextClassLoader 安全权限
+ // 利用新的 ClassLoader 来加载类
+ } catch (SecurityException e) {
+
+ } finally {
+ currentThread.setContextClassLoader(previousClassLoader);
+ }
+ }
+
+ private static void loadUser() { // 兼容或适配老的 ClassLoader 代码
+ // JAXB 通过线程上下文 ClassLoader 切换不同实现 SPI
+ // JAXB 1.x 2.x
+ // JDK 提供的 API 1.x
+ // 第三方包实现 2.x
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ classLoader.loadClass("User"); // 使用 V2
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+//class User { // V1
+//
+//}
+
+// Class User { // V2
+// }
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoadingDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoadingDemo.java"
new file mode 100644
index 0000000..787f4af
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassLoadingDemo.java"
@@ -0,0 +1,93 @@
+package com.segmentfault.deep.in.java;
+
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.stream.Stream;
+
+/**
+ * 类加载过程
+ */
+public class ClassLoadingDemo {
+
+ public static void main(String[] args) throws ClassNotFoundException {
+
+ // 当前 main 线程 ClassLoader
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ // 加载某个 Class 对象
+ // User user = ... -> load class
+
+ // 当前工程相对路径:stage-5/stage-5-lesson-1
+ // 当前工程绝对路径:${user.dir}/stage-5/stage-5-lesson-1
+ // 当前工程ClassPath :${user.dir}/stage-5/stage-5-lesson-1/target/classes
+ // User 类全名:com.segmentfault.deep.in.java.User
+ // User.class 文件路径:${ClassPath}/com/segmentfault/deep/in/java/User.class
+
+ String className = "com.segmentfault.deep.in.java.User";
+ // com/segmentfault/deep/in/java/User.class
+ String classFileName = className.replace('.', '/').concat(".class");
+ String classPath = System.getProperty("user.dir") + "/stage-5/stage-5-lesson-1/target/classes";
+ // User.class 类文件的绝对路径
+ File classFile = new File(classPath, classFileName);
+
+ // ClassLoader 也是对象,也会被 GC 管理
+ MyClassLoader myClassLoader = new MyClassLoader();
+ // .class 文件变为字节流 byte[],再定义 Class 对象
+ Class> userClass = myClassLoader.defineClass(className, classFile);
+
+ System.out.println("当前类对象:" + userClass);
+ Stream.of(userClass.getDeclaredFields())
+ .forEach(field -> {
+ System.out.println("当前字段信息:" + field);
+ });
+
+ Class> userClassFromThreadContextClassLoader = classLoader.loadClass(className);
+ // User.class 被 MyClassLoader 加载后,是否与线程上下文加载的 User.class 对象是否一致?
+ // 这个现象能够解释 Spring spring-boot-devtools 模块 Class!=Class 问题
+ System.out.println("userClass == userClassFromThreadContextClassLoader ? "
+ + (userClass == userClassFromThreadContextClassLoader));
+
+ // 重新替换掉线程上下文 ClassLoader
+ // myClassLoader -> Thread.currentThread().getContextClassLoader()
+ Thread.currentThread().setContextClassLoader(myClassLoader);
+ // 老的线程上下文 ClassLoader 是 MyClassLoader 的 parent,由于双亲委派,及时是 MyClassLoader 重新调用
+ // loadClass(String) 方法,也不会重新加载
+ Class> userClassFromMyClassLoader = classLoader.loadClass(className);
+ System.out.println("userClass == userClassFromMyClassLoader ? " +
+ (userClass == userClassFromMyClassLoader));
+
+ // 已加载 Class 是如何实现,目标方法: java.lang.ClassLoader.findLoadedClass0
+ System.out.println(
+ "userClassFromThreadContextClassLoader == userClassFromMyClassLoader ? " +
+ (userClassFromThreadContextClassLoader == userClassFromMyClassLoader));
+ }
+
+ static class MyClassLoader extends ClassLoader {
+
+ public MyClassLoader() {
+ // 当前线程上下文 ClassLoader 作为 Parent
+ super(Thread.currentThread().getContextClassLoader());
+ }
+
+ // 文件 -> 定义某个 Class
+ public Class> defineClass(String name, File classFile) {
+ // File classFile -> byte[]
+ byte[] bytes = loadBytes(classFile);
+ // 利用 ClassLoader defineClass 方法来定义 Class
+ // 可用于动态加载
+ return super.defineClass(name, bytes, 0, bytes.length);
+
+ }
+
+ private byte[] loadBytes(File classFile) {
+ byte[] bytes = null;
+ try {
+ bytes = FileUtils.readFileToByteArray(classFile);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return bytes;
+ }
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassObjectDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassObjectDemo.java"
new file mode 100644
index 0000000..e1590b0
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/ClassObjectDemo.java"
@@ -0,0 +1,33 @@
+package com.segmentfault.deep.in.java;
+
+/**
+ * 类对象示例代码
+ */
+public class ClassObjectDemo {
+
+ public static void main(String[] args) {
+
+ // ClassLoader 在加载类过程(验证)中,去重操作
+ // 验证:运行时校验 .class 文件(已经编译结果)
+ // .class 文件版版本 Java 5 泛型,JVM 版本过低版本不兼容
+ // 处理:参考《深入 Java 虚拟机》第二版
+ // 双亲委派(类加载以及类存储)
+ Class> objectClass = Object.class;
+
+ // ClassLoader
+
+ // 原生类型也有类对象
+ Class> intClass = int.class;
+
+ isPrimitive(objectClass);
+ isPrimitive(intClass);
+
+ // Object.class 和 int.class 均被 Bootstrap ClassLoader
+ // Bootstrap ClassLoader 在 Java 9 之前,就是 rt.jar
+ // 除 Bootstrap ClassLoader 之外,System ClassLoader, Application ClassLoader
+ }
+
+ private static void isPrimitive(Class klass) {
+ System.out.printf("类[%s] 是否属于原生类型:%s\n", klass.getName(), klass.isPrimitive());
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/User.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/User.java"
new file mode 100644
index 0000000..1a1a8bb
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-5/stage-5-lesson-1/src/main/java/com/segmentfault/deep/in/java/User.java"
@@ -0,0 +1,17 @@
+package com.segmentfault.deep.in.java;
+
+/**
+ * V1 版本拥有 ID 字段
+ */
+public class User {
+
+ private long id;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+}
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes.sln" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes.sln"
new file mode 100644
index 0000000..40f1d52
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes.sln"
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.438
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PosixThread_Attributes", "PosixThread_Attributes\PosixThread_Attributes.vcxproj", "{CFEF4222-68AC-4D9C-98D2-E0E2181277E4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Debug|x64.ActiveCfg = Debug|x64
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Debug|x64.Build.0 = Debug|x64
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Debug|x86.ActiveCfg = Debug|Win32
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Debug|x86.Build.0 = Debug|Win32
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Release|x64.ActiveCfg = Release|x64
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Release|x64.Build.0 = Release|x64
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Release|x86.ActiveCfg = Release|Win32
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B1D908A1-8B3F-4C04-9913-124FC142A4A3}
+ EndGlobalSection
+EndGlobal
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.cpp" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.cpp"
new file mode 100644
index 0000000..0b34693
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.cpp"
@@ -0,0 +1,43 @@
+// PosixThread_HelloWorld.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
+//
+
+#include "pch.h"
+#include
+#include
+
+using namespace std;
+
+
+int main()
+{
+ pthread_t t1;
+
+ // 申明 POSIX Thread 属性变量
+ pthread_attr_t attr;
+ // 申请线程栈大小(无符号整型) 512 K
+ size_t stack_size = 512 * 1000;
+
+ // 初始化 pthread_attr_t
+ pthread_attr_init(&attr);
+ // 设置 pthread_attr_t 栈大小 -> 512 K
+ pthread_attr_setstacksize(&attr, stack_size);
+
+ // 创建 t1 线程,并且将执行对象指向 void* helloWorld(void* ptr);
+ int result = pthread_create(&t1, &attr, helloWorld, NULL);
+
+ pthread_join(t1, NULL);
+ // 销毁 pthread_attr_t attr
+ pthread_attr_destroy(&attr);
+ //线程退出
+ pthread_exit(NULL);
+
+ return EXIT_SUCCESS;
+}
+
+void* helloWorld(void* ptr) {
+ pthread_t t = pthread_self();
+ //printf("Thread - Hello World \n");
+ cout << "Hello World" << endl;
+ return NULL;
+}
+
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj"
new file mode 100644
index 0000000..c5882e7
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj"
@@ -0,0 +1,171 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {CFEF4222-68AC-4D9C-98D2-E0E2181277E4}
+ Win32Proj
+ PosixThreadAttributes
+ 10.0.17763.0
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\include;$(IncludePath)
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\dll\x86;$(LibraryPath)
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\lib\x86\pthreadVC2.lib;%(AdditionalDependencies)
+
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj.filters" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj.filters"
new file mode 100644
index 0000000..9b6edfc
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj.filters"
@@ -0,0 +1,30 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 头文件
+
+
+
+
+ 源文件
+
+
+ 源文件
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj.user" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj.user"
new file mode 100644
index 0000000..be25078
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/PosixThread_Attributes.vcxproj.user"
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/pch.cpp" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/pch.cpp"
new file mode 100644
index 0000000..8eb50d0
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/pch.cpp"
@@ -0,0 +1,5 @@
+// pch.cpp: 与预编译标头对应的源文件;编译成功所必需的
+
+#include "pch.h"
+
+// 一般情况下,忽略此文件,但如果你使用的是预编译标头,请保留它。
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/pch.h" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/pch.h"
new file mode 100644
index 0000000..bd62e27
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Attributes/PosixThread_Attributes/pch.h"
@@ -0,0 +1,15 @@
+// 入门提示:
+// 1. 使用解决方案资源管理器窗口添加/管理文件
+// 2. 使用团队资源管理器窗口连接到源代码管理
+// 3. 使用输出窗口查看生成输出和其他消息
+// 4. 使用错误列表窗口查看错误
+// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
+// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
+
+#ifndef PCH_H
+#define PCH_H
+
+void* helloWorld(void* ptr);
+// TODO: 添加要在此处预编译的标头
+
+#endif //PCH_H
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld.sln" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld.sln"
new file mode 100644
index 0000000..086b867
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld.sln"
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.438
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PosixThread_HelloWorld", "PosixThread_HelloWorld\PosixThread_HelloWorld.vcxproj", "{F6804956-219B-4853-A162-6F85685868C5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F6804956-219B-4853-A162-6F85685868C5}.Debug|x64.ActiveCfg = Debug|x64
+ {F6804956-219B-4853-A162-6F85685868C5}.Debug|x64.Build.0 = Debug|x64
+ {F6804956-219B-4853-A162-6F85685868C5}.Debug|x86.ActiveCfg = Debug|Win32
+ {F6804956-219B-4853-A162-6F85685868C5}.Debug|x86.Build.0 = Debug|Win32
+ {F6804956-219B-4853-A162-6F85685868C5}.Release|x64.ActiveCfg = Release|x64
+ {F6804956-219B-4853-A162-6F85685868C5}.Release|x64.Build.0 = Release|x64
+ {F6804956-219B-4853-A162-6F85685868C5}.Release|x86.ActiveCfg = Release|Win32
+ {F6804956-219B-4853-A162-6F85685868C5}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {EC1A5E13-B1F6-4EE9-A4CF-457F212A7707}
+ EndGlobalSection
+EndGlobal
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.cpp" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.cpp"
new file mode 100644
index 0000000..a51c3a9
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.cpp"
@@ -0,0 +1,36 @@
+// PosixThread_HelloWorld.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
+//
+
+#include "pch.h"
+#include
+#include
+
+using namespace std;
+
+
+int main()
+{
+ pthread_t t1;
+
+ pthread_attr_t attr;
+
+ size_t stack_size = 512 * 1000;
+
+ pthread_attr_setstacksize(&attr, stack_size);
+
+ // 创建 t1 线程,并且将执行对象指向 void* helloWorld(void* ptr);
+ int result = pthread_create(&t1,&attr, helloWorld, NULL);
+
+
+ pthread_join(t1, NULL);
+
+ return EXIT_SUCCESS;
+}
+
+void* helloWorld(void* ptr) {
+ pthread_t t = pthread_self();
+ //printf("Thread - Hello World \n");
+ cout << "Hello World" << endl;
+ return NULL;
+}
+
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj"
new file mode 100644
index 0000000..2dabff4
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj"
@@ -0,0 +1,171 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {F6804956-219B-4853-A162-6F85685868C5}
+ Win32Proj
+ PosixThreadHelloWorld
+ 10.0.17763.0
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\include;$(IncludePath)
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\lib;$(LibraryPath)
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\lib\x86\pthreadVC2.lib;%(AdditionalDependencies)
+
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj.filters" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj.filters"
new file mode 100644
index 0000000..1dcd5b5
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj.filters"
@@ -0,0 +1,30 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 头文件
+
+
+
+
+ 源文件
+
+
+ 源文件
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj.user" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj.user"
new file mode 100644
index 0000000..be25078
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/PosixThread_HelloWorld.vcxproj.user"
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/pch.cpp" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/pch.cpp"
new file mode 100644
index 0000000..8eb50d0
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/pch.cpp"
@@ -0,0 +1,5 @@
+// pch.cpp: 与预编译标头对应的源文件;编译成功所必需的
+
+#include "pch.h"
+
+// 一般情况下,忽略此文件,但如果你使用的是预编译标头,请保留它。
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/pch.h" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/pch.h"
new file mode 100644
index 0000000..3dc472d
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_HelloWorld/PosixThread_HelloWorld/pch.h"
@@ -0,0 +1,16 @@
+// 入门提示:
+// 1. 使用解决方案资源管理器窗口添加/管理文件
+// 2. 使用团队资源管理器窗口连接到源代码管理
+// 3. 使用输出窗口查看生成输出和其他消息
+// 4. 使用错误列表窗口查看错误
+// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
+// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
+
+#ifndef PCH_H
+#define PCH_H
+
+// TODO: 添加要在此处预编译的标头
+
+void* helloWorld(void* ptr);
+
+#endif //PCH_H
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync.sln" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync.sln"
new file mode 100644
index 0000000..0d143e5
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync.sln"
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.438
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PosixThread_Sync", "PosixThread_Sync\PosixThread_Sync.vcxproj", "{186FD364-9C46-475A-B433-7C56CCA71E90}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Debug|x64.ActiveCfg = Debug|x64
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Debug|x64.Build.0 = Debug|x64
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Debug|x86.ActiveCfg = Debug|Win32
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Debug|x86.Build.0 = Debug|Win32
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Release|x64.ActiveCfg = Release|x64
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Release|x64.Build.0 = Release|x64
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Release|x86.ActiveCfg = Release|Win32
+ {186FD364-9C46-475A-B433-7C56CCA71E90}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D6EDBBD3-9280-49C2-9BCB-2A6D087E8082}
+ EndGlobalSection
+EndGlobal
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.cpp" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.cpp"
new file mode 100644
index 0000000..a910ae8
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.cpp"
@@ -0,0 +1,82 @@
+// PosixThread_Sync.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
+//
+
+#include "pch.h"
+#include
+#include
+
+int counter = 0;
+
+// 定义互斥对象
+pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
+
+// 定义条件变量
+pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
+
+void* addCounter(void* ptr);
+
+void* minusCounter(void* ptr);
+
+int main()
+{
+ pthread_t t1;
+ pthread_t t2;
+
+ pthread_create(&t1, NULL, addCounter, NULL);
+ pthread_create(&t2, NULL, minusCounter, NULL);
+
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+
+ std::cout << "Counter : " << counter << std::endl;
+
+ return EXIT_SUCCESS;
+}
+
+void* minusCounter(void* ptr) {
+ for (int i=0;i<100;i++) {
+
+ // lock 加锁
+ pthread_mutex_lock(&mutex1);
+ std::cout << "minusCounter - Before Counter : " << counter << std::endl;
+
+ if (counter < 9 && counter > 1) { // 消费数据,唤起生产者线程
+ counter--;
+ pthread_cond_signal(&condition_var);
+ }
+
+ if (counter < 1) { // 当数据不足时,阻塞当前消费者线程
+ pthread_cond_wait(&condition_var, &mutex1);
+ }
+
+
+ std::cout << "minusCounter - After Counter : " << counter << std::endl;
+ // unlock 解锁
+ pthread_mutex_unlock(&mutex1);
+ }
+ return NULL;
+}
+
+void* addCounter(void* ptr) {
+ for (int i = 0; i < 100; i++) {
+ // lock 加锁
+ pthread_mutex_lock(&mutex1);
+ std::cout << "addCounter - Before Counter : " << counter << std::endl;
+
+ if (counter < 9) { // 当数据不到阈值时,唤起当前消费者线程
+ counter++;
+ pthread_cond_signal(&condition_var);
+ }
+
+ if (counter > 9) { // 当数据达到阈值时,阻塞当前生产者线程
+ pthread_cond_wait(&condition_var, &mutex1);
+ }
+
+ std::cout << "addCounter - After Counter : " << counter << std::endl;
+ // unlock 解锁
+ pthread_mutex_unlock(&mutex1);
+ }
+ return NULL;
+}
+
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj"
new file mode 100644
index 0000000..19d03b2
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj"
@@ -0,0 +1,174 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {186FD364-9C46-475A-B433-7C56CCA71E90}
+ Win32Proj
+ PosixThreadSync
+ 10.0.17763.0
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\include;$(IncludePath)
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\dll\x86;$(LibraryPath)
+
+
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\include;$(IncludePath)
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\dll\x86;$(LibraryPath)
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\lib\x86\pthreadVC2.lib;%(AdditionalDependencies)
+
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ E:\software\dev\CPP\pthreads-w32-2-9-1\Pre-built.2\lib\x86\pthreadVC2.lib;%(AdditionalDependencies)
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj.filters" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj.filters"
new file mode 100644
index 0000000..19b500b
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj.filters"
@@ -0,0 +1,30 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 头文件
+
+
+
+
+ 源文件
+
+
+ 源文件
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj.user" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj.user"
new file mode 100644
index 0000000..be25078
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/PosixThread_Sync.vcxproj.user"
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/pch.cpp" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/pch.cpp"
new file mode 100644
index 0000000..8eb50d0
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/pch.cpp"
@@ -0,0 +1,5 @@
+// pch.cpp: 与预编译标头对应的源文件;编译成功所必需的
+
+#include "pch.h"
+
+// 一般情况下,忽略此文件,但如果你使用的是预编译标头,请保留它。
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/pch.h" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/pch.h"
new file mode 100644
index 0000000..69bf59d
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/visual-studio-workspace/PosixThread_Sync/PosixThread_Sync/pch.h"
@@ -0,0 +1,14 @@
+// 入门提示:
+// 1. 使用解决方案资源管理器窗口添加/管理文件
+// 2. 使用团队资源管理器窗口连接到源代码管理
+// 3. 使用输出窗口查看生成输出和其他消息
+// 4. 使用错误列表窗口查看错误
+// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
+// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
+
+#ifndef PCH_H
+#define PCH_H
+
+// TODO: 添加要在此处预编译的标头
+
+#endif //PCH_H
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\272\277\347\250\213\344\270\216\350\277\233\347\250\213/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212Java \347\272\277\347\250\213\344\270\216\350\277\233\347\250\213\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\272\277\347\250\213\344\270\216\350\277\233\347\250\213/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212Java \347\272\277\347\250\213\344\270\216\350\277\233\347\250\213\343\200\213.pdf"
new file mode 100644
index 0000000..05e6211
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\272\277\347\250\213\344\270\216\350\277\233\347\250\213/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212Java \347\272\277\347\250\213\344\270\216\350\277\233\347\250\213\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250/Multithreading-and-Concurrency-Questions.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250/Multithreading-and-Concurrency-Questions.pdf"
new file mode 100644
index 0000000..93e9275
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250/Multithreading-and-Concurrency-Questions.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\270\211\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\270\211\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250\343\200\213.pdf"
new file mode 100644
index 0000000..106481c
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\270\211\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\345\237\272\347\241\200\350\277\220\347\224\250\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Christoph Lameter, Ph.D. - 2005 - Effective Synchronization.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Christoph Lameter, Ph.D. - 2005 - Effective Synchronization.pdf"
new file mode 100644
index 0000000..76d02ac
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Christoph Lameter, Ph.D. - 2005 - Effective Synchronization.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Dave Dice - 2006 - Synchronization in Java SE 6(HotSpot).pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Dave Dice - 2006 - Synchronization in Java SE 6(HotSpot).pdf"
new file mode 100644
index 0000000..f93e6a3
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Dave Dice - 2006 - Synchronization in Java SE 6(HotSpot).pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Thin Locks Featherweight Synchronization for Java.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Thin Locks Featherweight Synchronization for Java.pdf"
new file mode 100644
index 0000000..70a03e1
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/Thin Locks Featherweight Synchronization for Java.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\272\214\350\212\202 \343\200\212Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\272\214\350\212\202 \343\200\212Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200\343\200\213.pdf"
new file mode 100644
index 0000000..8536d52
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\344\272\214\350\212\202 \343\200\212Java \345\271\266\345\217\221\347\274\226\347\250\213\345\237\272\347\241\200\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\345\233\233\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\345\233\233\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250\343\200\213.pdf"
new file mode 100644
index 0000000..502c3d6
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\345\233\233\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\233\270\345\205\263\350\265\204\346\226\231/2006 - Memory Management in the Java HotSpot\342\204\242 Virtual Machine .pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\233\270\345\205\263\350\265\204\346\226\231/2006 - Memory Management in the Java HotSpot\342\204\242 Virtual Machine .pdf"
new file mode 100644
index 0000000..5f113ca
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\233\270\345\205\263\350\265\204\346\226\231/2006 - Memory Management in the Java HotSpot\342\204\242 Virtual Machine .pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\261\273\347\232\204\345\261\202\346\254\241/README.md" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\261\273\347\232\204\345\261\202\346\254\241/README.md"
new file mode 100644
index 0000000..246e4b3
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\261\273\347\232\204\345\261\202\346\254\241/README.md"
@@ -0,0 +1,334 @@
+# 「一入 Java 深似海 」系列 第五期 第一节 《Java 类的层次》
+
+
+
+## JVM 小常识
+
+### native 源码路径
+
+通常 XXX.java 出现 native 方法时,对应的 JVM 源码实现则为 XXX.c 文件,比如:
+
+- java.lang.Class -> share/native/java/lang/Class.c
+- java.lang.ClassLoader -> share/native/java/lang/ClassLoader.c
+
+
+
+### native 方法注册机制
+
+Java Class 文件中的 `registerNatives()` 方法,以 `java.lang.Class` 为例:
+
+```java
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ }
+```
+
+
+
+对应的 JVM 实现:
+
+```c
+JNIEXPORT void JNICALL
+Java_java_lang_Class_registerNatives(JNIEnv *env, jclass cls)
+{
+ methods[1].fnPtr = (void *)(*env)->GetSuperclass;
+ (*env)->RegisterNatives(env, cls, methods,
+ sizeof(methods)/sizeof(JNINativeMethod));
+}
+```
+
+
+
+其中 `JNINativeMethod` 是数据结构,`methods` 是函数指针(地址):
+
+```c
+static JNINativeMethod methods[] = {
+ {"getName0", "()" STR, (void *)&JVM_GetClassName},
+ {"getSuperclass", "()" CLS, NULL},
+ {"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces},
+ {"getClassLoader0", "()" JCL, (void *)&JVM_GetClassLoader},
+ {"isInterface", "()Z", (void *)&JVM_IsInterface},
+ {"getSigners", "()[" OBJ, (void *)&JVM_GetClassSigners},
+ {"setSigners", "([" OBJ ")V", (void *)&JVM_SetClassSigners},
+ {"isArray", "()Z", (void *)&JVM_IsArrayClass},
+ {"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass},
+ {"getComponentType", "()" CLS, (void *)&JVM_GetComponentType},
+ {"getModifiers", "()I", (void *)&JVM_GetClassModifiers},
+ {"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields},
+ {"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods},
+ {"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors},
+ {"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain},
+ {"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
+ {"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass},
+ {"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature},
+ {"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
+ {"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool},
+ {"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},
+ {"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo},
+ {"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations},
+};
+```
+
+例如:`getName0` 方法是来自于 Java native 方法名, `JVM_GetClassName` 是 JVM C 实现函数:
+
+```c
+JVM_ENTRY(jstring, JVM_GetClassName(JNIEnv *env, jclass cls))
+ assert (cls != NULL, "illegal class");
+ JVMWrapper("JVM_GetClassName");
+ JvmtiVMObjectAllocEventCollector oam;
+ ResourceMark rm(THREAD);
+ const char* name;
+ if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
+ name = type2name(java_lang_Class::primitive_type(JNIHandles::resolve(cls)));
+ } else {
+ // Consider caching interned string in Klass
+ Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
+ assert(k->is_klass(), "just checking");
+ name = k->external_name();
+ }
+ oop result = StringTable::intern((char*) name, CHECK_NULL);
+ return (jstring) JNIHandles::make_local(env, result);
+JVM_END
+```
+
+
+
+### JVM Header 与 Source 文件的映射
+
+header 文件是`.hpp` 存储,source 文件是对应的 `.cpp` 文件。
+
+
+
+### 重要方法 JNIHandles::resolve
+
+将 JNI jxxx 对象转化成 oop 对象
+
+
+
+### 重要文件
+
+
+
+#### allocation.hpp 以及 allocation.cpp 文件
+
+- ResourceObj
+
+For objects allocated in the resource area (see resourceArea.hpp).
+
+- CHeapObj
+
+ For objects allocated in the C-heap (managed by: free & malloc).
+
+- StackObj
+
+For objects allocated on the stack.
+
+- ValueObj
+
+For embedded objects.
+
+- AllStatic
+
+For classes used as name spaces.
+
+- MetaspaceObj
+
+For classes in Metaspace (class data)
+
+
+
+
+## Java 类对象
+
+
+
+### 基本概念
+
+类对象 = Class 对象 = `.class`
+
+
+
+### 基本分类
+
+对象类型:`Object.class` 以及派生类
+
+原生类型:`int`、`long` 等
+
+类定义 = 原生+对象字段作为存储状态 + 方法来控制状态行为
+
+
+
+
+
+### 基础知识
+
+
+
+#### 类的版本
+
+类的版本属于 Java 虚拟机规范:JVM 以及 Class
+
+> Java 语言规范:JDK 和 Java 运行时语法、行为控制
+
+
+
+#### 编译器
+
+- javac - Java 程序编写的可执行程序(since 6 开始,通过 Java 实现,6 之前,native 实现)(Maven 编译器插件)
+
+- ecj - eclipse 编译器,JSP 编译器(JSP 翻译 JSP .java 文件,编译成 JSP .class 文件),Eclipse IDE(注意 Java 泛型差异)
+
+ > JSP - JspServlet 运行时参数 development = true -> false
+
+> javac 与 eclipse 编译器不一定完全兼容
+
+
+
+#### Class 与 ClassLoader 之间的关系
+
+Java Class 的元(meta)信息定义在 .class 文件中,类版本号、魔数、类结构、字节码等等
+
+
+
+ClassLoader 是按照字节码规则加载 Class 资源(.class 文件 ,网络传输),形成 Java 运行时 Class 对象
+
+
+
+1. ClassLoader#loadClass 是用于加载 Class 对象,那么 Class 对象是被那个 ClassLoader 加载的?
+
+Class 对象是通过 ClassLoader 的 loadClass 方法加载并获取,相反,ClassLoader 可以通过 Class 的 getClassLoader() 获取。
+
+
+
+2. Class 对象可能来自于文件(如 .class 文件),也可能是来自于网络,那么 ClassLoader 是如何将这些资源变为 Class 对象
+
+.class 文件或者网络 I/O 都是字节码流(Stream),ClassLoader 能够把二进制流解析为 Class 对象,通过复用 ClassLoader#defineClass 方法实现(重)定义 Class 类,比如 Groovy 动态加载类。
+
+
+
+3. Class 对象与 ClassLoader#loadClass 方法之间的关联?
+
+ClassLoader#loadClass 时,通过 ClassPath 关联类资源(文件、网络),来获取字节码流,再被定义 Class 对象。
+
+
+
+ClassLoader 类加载顺序:
+
+- 尝试已加载的类( ClassLoader 层次性,要不当前 ClassLoader,要不其 Parent)
+
+- 尝试双亲委派加载类(直到 Bootstrap ClassLoader 加载不到)
+- 执行 findClass(String) 方法(ClassLoader 是一个抛出 ClassNotFoundException 实现,子类可覆盖该方法)
+ - jdk.internal.loader.BuiltinClassLoader#findClass
+ - ClassPath = URLClassPath
+
+
+
+#### 系统 ClassLaoder 实现
+
+
+
+##### Java 12 中的实现
+
+- jdk.internal.loader.ClassLoaders.AppClassLoader
+ - jdk.internal.loader.BuiltinClassLoader
+ - java.security.SecureClassLoader
+ - java.lang.ClassLoader
+
+
+
+#### ClassLoader 双亲委派
+
+
+
+`ClassLoader` 提供 parent 字段引用双亲 ClassLoader,通常调用 loadClass(String) 方法:
+
+```java
+ public Class> loadClass(String name) throws ClassNotFoundException {
+ return loadClass(name, false);
+ }
+```
+
+双亲委派类加载实际是通过 `parent` 字段递归,找到根 ClassLoader。实际上,根 ClassLoader = Bootstrap ClassLoader
+
+loadClass(String) 方法 不仅可被 Java 程序调用,比如:Spring BeanFactory 类加载时,也可能被 JVM 调用,比如:new XXX()时,XXX 将作为类被加载。
+
+#### JVM 调用 loadClass 方法的时机
+
+- new XXX() 时
+- 调用 XXX.yyy 静态字段
+- 通过反射 API - `Class.forName` 或者 ` ClassLoader.loadClass`
+
+
+
+#### 原生类型 Class 对象
+
+
+
+```java
+// 原生类型也有类对象
+Class> intClas = int.class;
+```
+
+#### Bootstrap ClassLoader
+
+等价于:
+```java
+ Class> findBootstrapClassOrNull(String name) {
+ if (!checkName(name)) return null;
+
+ return findBootstrapClass(name);
+ }
+
+ // return null if not found
+ private native Class> findBootstrapClass(String name);
+```
+
+
+
+#### ClassLoader
+
+Bootstrap ClassLoader 是无法获取,最接近 Java 程序的 ClassLoader 是 System ClassLoader
+
+
+
+##### 系统 ClassLoader
+
+通过 `java.lang.ClassLoader#getSystemClassLoader` 方法获取。
+
+##### 应用 ClassLoader
+
+可以通过当前 Thread 上下文 ClassLoader 获取(不完全一定):`java.lang.Thread#getContextClassLoader`
+
+
+
+
+
+#### 相关书籍
+
+《深入 Java 虚拟机》- 1999 年
+
+
+
+## Java 类存储
+
+Java 中的 Class 类 对应的 JVM 结构 Klass 类,由于Class 类存储从 Java 8 + 放置 Metadata 区域,不在是 Perm:
+
+```c++
+class Klass : public Metadata {
+
+}
+```
+
+
+
+>
+
+
+
+## Java 类装载和卸载
+
+
+
+
+
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\261\273\347\232\204\345\261\202\346\254\241/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212Java \347\261\273\347\232\204\345\261\202\346\254\241\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\261\273\347\232\204\345\261\202\346\254\241/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212Java \347\261\273\347\232\204\345\261\202\346\254\241\343\200\213.pdf"
new file mode 100644
index 0000000..a911e82
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\200\350\212\202 Java \347\261\273\347\232\204\345\261\202\346\254\241/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212Java \347\261\273\347\232\204\345\261\202\346\254\241\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\211\350\212\202 Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\212\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\270\211\350\212\202 \343\200\212Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\212\357\274\211\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\211\350\212\202 Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\212\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\270\211\350\212\202 \343\200\212Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\212\357\274\211\343\200\213.pdf"
new file mode 100644
index 0000000..a7b5c6f
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\270\211\350\212\202 Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\212\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\270\211\350\212\202 \343\200\212Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\212\357\274\211\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\272\224\350\212\202 Java \346\226\260\345\236\213\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\272\224\350\212\202 \343\200\212Java \346\226\260\345\236\213\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\272\224\350\212\202 Java \346\226\260\345\236\213\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\272\224\350\212\202 \343\200\212Java \346\226\260\345\236\213\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\343\200\213.pdf"
new file mode 100644
index 0000000..033f671
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\344\272\224\350\212\202 Java \346\226\260\345\236\213\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\344\272\224\350\212\202 \343\200\212Java \346\226\260\345\236\213\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\345\233\233\350\212\202 Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\213\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\213\357\274\211\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\345\233\233\350\212\202 Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\213\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\213\357\274\211\343\200\213.pdf"
new file mode 100644
index 0000000..4f57027
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\272\224\346\234\237/\347\254\254\345\233\233\350\212\202 Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\213\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\272\224\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \344\274\240\347\273\237\345\236\203\345\234\276\346\224\266\351\233\206\345\231\250\357\274\210\344\270\213\357\274\211\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\270\200\350\212\202 POSIX Thread/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212POSIX Thread\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\270\200\350\212\202 POSIX Thread/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212POSIX Thread\343\200\213.pdf"
new file mode 100644
index 0000000..5e05390
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\270\200\350\212\202 POSIX Thread/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\270\200\350\212\202 \343\200\212POSIX Thread\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\357\274\210J.U.C\357\274\211 AQS \345\216\237\347\220\206/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\270\211\350\212\202\343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\357\274\210J.U.C\357\274\211 AQS \345\216\237\347\220\206\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\357\274\210J.U.C\357\274\211 AQS \345\216\237\347\220\206/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\270\211\350\212\202\343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\357\274\210J.U.C\357\274\211 AQS \345\216\237\347\220\206\343\200\213.pdf"
new file mode 100644
index 0000000..4fbeb01
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\270\211\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\357\274\210J.U.C\357\274\211 AQS \345\216\237\347\220\206/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\270\211\350\212\202\343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\357\274\210J.U.C\357\274\211 AQS \345\216\237\347\220\206\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/JSR-133 Java Memory Model and Thread Specification.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/JSR-133 Java Memory Model and Thread Specification.pdf"
new file mode 100644
index 0000000..c07d385
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/JSR-133 Java Memory Model and Thread Specification.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/JavaOne 2004 - The New Java\342\204\242 Technology Memory Model.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/JavaOne 2004 - The New Java\342\204\242 Technology Memory Model.pdf"
new file mode 100644
index 0000000..739beab
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/JavaOne 2004 - The New Java\342\204\242 Technology Memory Model.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/The Java Language Specification Java SE 12 Edition.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/The Java Language Specification Java SE 12 Edition.pdf"
new file mode 100644
index 0000000..0ce39bc
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/The Java Language Specification Java SE 12 Edition.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\272\214\350\212\202\343\200\212Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\272\214\350\212\202\343\200\212Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211\343\200\213.pdf"
new file mode 100644
index 0000000..b43767b
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\344\272\214\350\212\202\343\200\212Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211\343\200\213.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/\347\233\270\345\205\263\351\223\276\346\216\245.txt" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/\347\233\270\345\205\263\351\223\276\346\216\245.txt"
new file mode 100644
index 0000000..4329d01
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\344\272\214\350\212\202 Java \345\206\205\345\255\230\346\250\241\345\236\213\357\274\210Java Memory Model\357\274\211/\347\233\270\345\205\263\351\223\276\346\216\245.txt"
@@ -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
\ No newline at end of file
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/2006 - Eliminating synchronization-related atomic operations with biased locking and bulk rebiasing .pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/2006 - Eliminating synchronization-related atomic operations with biased locking and bulk rebiasing .pdf"
new file mode 100644
index 0000000..4b4ad90
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/2006 - Eliminating synchronization-related atomic operations with biased locking and bulk rebiasing .pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/Biased Locking in HotSpot - Dave - 2006.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/Biased Locking in HotSpot - Dave - 2006.pdf"
new file mode 100644
index 0000000..eca38e3
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/Biased Locking in HotSpot - Dave - 2006.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/README.md" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/README.md"
new file mode 100644
index 0000000..016b446
--- /dev/null
+++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/README.md"
@@ -0,0 +1,546 @@
+# `JVM 并发实现
+
+
+
+## Java 线程 - java.lang.Thread
+
+
+
+### 预备知识
+
+- C++ Basic
+- JNI - Java Native Interface
+- POSIX Thread
+
+
+
+### java.lang.Thread API 定义
+
+#### 基本操作
+
+##### 创建 - `new Thread()`
+
+Thread 对象 new 实际普通的 Java 对象创建,不涉及 JVM 或者 OS 线程创建和启动
+
+JNI 类型:`jobject`
+
+##### 启动 - `Thread#start()`
+
+ `Thread#start()` 引导线程启动,不一定马上启动(非阻塞),终究会 `Thread#run()` 方法(回调)
+
+ `Thread#start()` 方法定义:
+
+```java
+public synchronized void start() { // 线程安全
+ ...
+ group.add(this); // 将当前线程添加到所在 ThreadGroup
+ ...
+ try {
+ start0(); // Native 方法
+ }
+ ...
+}
+
+private native void start0(); // JNI Java 调用 JVM 方法
+```
+
+
+
+Java 类名称: `java.lang.Thread `
+
+```java
+public
+class Thread implements Runnable {
+ /* Make sure registerNatives is the first thing does. */
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ }
+ ...
+}
+```
+
+JNI 方法名称(C 函数):
+
+```c++
+JNIEXPORT void JNICALL
+Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
+{
+ (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
+}
+```
+
+
+
+java.lang.Thread native 方法的映射表:
+
+```c++
+static JNINativeMethod methods[] = {
+ {"start0", "()V", (void *)&JVM_StartThread},
+ {"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
+ {"isAlive", "()Z", (void *)&JVM_IsThreadAlive}
+ ...
+};
+```
+
+
+
+方法签名:`java.lang.Thread#start0()`
+
+Native 方法:`JVM_StartThread`
+
+```c++
+/*
+ * java.lang.Thread
+ */
+JNIEXPORT void JNICALL
+JVM_StartThread(JNIEnv *env, jobject thread);
+```
+
+> 方法声明位置:`/jdk/src/share/javavm/export/jvm.h`
+
+实现入口:
+
+```c++
+JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
+...
+{
+ jlong size =
+ java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
+ ...
+ size_t sz = size > 0 ? (size_t) size : 0;
+ native_thread = new JavaThread(&thread_entry, sz);
+ ...
+}
+```
+
+`native_thread` 创建了 `JavaThread` 类型对象,第一个构造参数 `&thread_entry`,即函数指针(引用函数 `thread_entry`):
+
+```c++
+static void thread_entry(JavaThread* thread, TRAPS) {
+ HandleMark hm(THREAD);
+ Handle obj(THREAD, thread->threadObj()); // 1
+ JavaValue result(T_VOID);
+ JavaCalls::call_virtual(&result, // 2
+ obj, // 3
+ KlassHandle(THREAD, SystemDictionary::Thread_klass()), // 4
+ vmSymbols::run_method_name(), // 5
+ vmSymbols::void_method_signature(), // 6
+ THREAD);
+}
+```
+
+1. `thread->threadObject()` 返回了 Java 代码创建 `java.lang.Thread` 对象
+2. 调用 JVM C++ 对象虚拟方法(多态)
+3. obj `java.lang.Thread` 对象包装
+4. java.lang.Thread 类对象
+5. `java.lang.Thread#run()` 方法名称
+6. `void` 方法签名
+
+综上所述,`thread_entry` 方法执行目的是要执行 `java.lang.Thread` 对象的`run()` 方法
+
+
+
+分析 `JavaThread::JavaThread` 构造器:
+
+```c++
+JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz)
+ ...
+{
+ ...
+ set_entry_point(entry_point); // 设置 thread_entry 函数到当前对象
+ ...
+ os::create_thread(this, thr_type, stack_sz);
+ ...
+}
+```
+
+第一个构造参数 `entry_point` 是 `ThreadFunction`, `entry_point` 实际指向函数 - `thread_entry`,`thread_entry` 函数会被 `JavaThread` 对象作为成员变量保存,接下来执行 `os::create_thread(this, thr_type, stack_sz);` 方法,以 Linux 实现为例:
+
+```java
+bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
+ assert(thread->osthread() == NULL, "caller responsible");
+
+ // Allocate the OSThread object
+ OSThread* osthread = new OSThread(NULL, NULL);
+ if (osthread == NULL) {
+ return false;
+ }
+
+ // set the correct thread state
+ osthread->set_thread_type(thr_type);
+
+ // Initial state is ALLOCATED but not INITIALIZED
+ osthread->set_state(ALLOCATED);
+
+ thread->set_osthread(osthread);
+
+ // init thread attributes
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ ...
+ pthread_t tid;
+ int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
+
+ pthread_attr_destroy(&attr);
+
+ ...
+ return true;
+}
+```
+
+`java.lang.Thread#start0()` -> JVM JNI -> POSIX Thread `pthread_create`
+
+`java_start` 函数就是实际 JVM 执行操作:
+
+```c++
+static void *java_start(Thread *thread) {
+ ...
+ // call one more level start routine
+ thread->run();
+
+ return 0;
+}
+```
+
+参数 `thread` 实际为 `JavaThread` 对象,`thread->run()` 调用实际是 `JavaThread::run()` 方法的执行:
+
+```c++
+void JavaThread::run() {
+ ...
+ thread_main_inner();
+ // Note, thread is no longer valid at this point!
+}
+
+void JavaThread::thread_main_inner() {
+ ...
+ if (!this->has_pending_exception() &&
+ !java_lang_Thread::is_stillborn(this->threadObj())) {
+ {
+ ResourceMark rm(this);
+ this->set_native_thread_name(this->get_thread_name());
+ }
+ HandleMark hm(this);
+ this->entry_point()(this, this);
+ }
+
+ DTRACE_THREAD_PROBE(stop, this);
+
+ this->exit(false);
+ delete this;
+}
+```
+
+`this->entry_point` 是 `JavaThread` 成员变量,指向 `thread_entry` 函数:
+
+```sequence
+Thread.start0() -> JVM_StartThread : JVM Native 调用
+JVM_StartThread -> new JavaThread() : 创建一个 JavaThread() 对象
+new JavaThread() -> os_create_thread() : 创建线程(OS 相关的)
+os_create_thread() -> pthread_create() : 创建 POSIX Thread
+pthread_create() -> java_start() : 线程启动并回调 java_start()
+java_start() -> JavaThread_run() : 调用 JavaThread run() 方法
+JavaThread_run() -> thread_main_inner() : 内部调用
+thread_main_inner() -> entry_point() : entry_point 指向 thread_entry()
+thread_entry() -> java.lang.Thread.run() : 回调 Java Thread run() 方法
+```
+
+当 `java.lang.Thread#start()` 方法调用完成,JVM 所创建的`JavaThread`对象就移除: `delete this`
+
+
+
+##### 完成 - `Thread#join()`
+
+`java.lang.Thread#join()` 底层使用 `java.lang.Object#wait(long)` 方法实现:
+
+```java
+ public final synchronized void join(long millis)
+ throws InterruptedException {
+ ...
+ if (millis == 0) {
+ while (isAlive()) {
+ wait(0);
+ }
+ }
+ ...
+ }
+```
+
+ `java.lang.Object#wait(long)` 方法:
+
+```java
+public class Object {
+
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ }
+ ...
+ public final native void wait(long timeoutMillis) throws InterruptedException;
+ ...
+}
+```
+
+Object Native 实现:jdk/src/share/native/java/lang/Object.c
+
+```c++
+static JNINativeMethod methods[] = {
+ {"hashCode", "()I", (void *)&JVM_IHashCode},
+ {"wait", "(J)V", (void *)&JVM_MonitorWait},
+ {"notify", "()V", (void *)&JVM_MonitorNotify},
+ {"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
+ {"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
+};
+```
+
+`wait(long)` 方法映射 `JVM_MonitorWait`:
+
+```c++
+JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))
+ JVMWrapper("JVM_MonitorWait");
+ Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
+ JavaThreadInObjectWaitState jtiows(thread, ms != 0);
+ if (JvmtiExport::should_post_monitor_wait()) {
+ JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);
+ }
+ ObjectSynchronizer::wait(obj, ms, CHECK); // 1
+JVM_END
+```
+
+1. ObjectSynchronizer::wait(obj, ms, CHECK):
+
+```c++
+
+```
+
+
+
+wait() 方法执行前提,当前线程获得锁(synchronized)
+
+T1-> 获得锁(synchronized ) -> wait() -> 释放锁
+
+T2(等待获得锁)
+
+T3
+
+
+
+`Object#wait()`
+
+
+
+Object -> Object Monitor -> WaitSet
+
+```java
+Object monitor = new Object();
+synchronized(monitor) {
+ if(true){
+ monitor.wait(); // monitor WaitSet {T1 -> T2 -> T3}
+ }
+}
+
+synchronized(monitor) {
+ if(true){
+ monitor.notify(); // T4 monitor WaitSet pop() T1
+ }
+}
+```
+
+
+
+WaitSet 属于 ObjectMonitor 成员:
+
+```c++
+class ObjectMonitor {
+ ...
+ protected:
+ ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
+}
+```
+
+_WaitSet 是 `ObjectWaiter` 类型对象,属于双向队列节点:
+
+```c++
+class ObjectWaiter : public StackObj {
+ public:
+ ...
+ ObjectWaiter * volatile _next; // 下一个节点(Waiter)
+ ObjectWaiter * volatile _prev; // 上一个节点(Waiter)
+ Thread* _thread;
+ jlong _notifier_tid;
+ ParkEvent * _event;
+ volatile int _notified ;
+ volatile TStates TState ;
+ Sorted _Sorted ; // List placement disposition
+ bool _active ; // Contention monitoring is enabled
+ public:
+ ObjectWaiter(Thread* thread);
+
+ void wait_reenter_begin(ObjectMonitor *mon);
+ void wait_reenter_end(ObjectMonitor *mon);
+};
+```
+
+JVM `ObjectWaiter` 类似于 Java AQS `AbstractQueuedSynchronizer.Node`
+
+
+
+ `ObjectWaiter` 属于 CLH (双向)队列节点(自旋锁)
+
+```c++
+void Thread::SpinAcquire (volatile int * adr, const char * LockName) {
+ ...
+ for (;;) {
+ while (*adr != 0) {
+ ++ctr ;
+ if ((ctr & 0xFFF) == 0 || !os::is_MP()) {
+ if (Yields > 5) {
+ // Consider using a simple NakedSleep() instead.
+ // Then SpinAcquire could be called by non-JVM threads
+ Thread::current()->_ParkEvent->park(1) ;
+ } else {
+ os::NakedYield() ;
+ ++Yields ;
+ }
+ } else {
+ SpinPause() ;
+ }
+ }
+ if (Atomic::cmpxchg (1, adr, 0) == 0) return ;
+ }
+ ...
+}
+```
+
+
+
+`AbstractQueuedSynchronizer.Node` 属于 CLH 变种(双向)队列节点(阻塞):
+
+```java
+ private final boolean parkAndCheckInterrupt() {
+ LockSupport.park(this);
+ return Thread.interrupted();
+ }
+```
+
+
+
+JVM `ParkEvent->park` 以及 JDK `LockSupport.park(this)` 底层同为 `pthread_cond_wait` 函数。
+
+相反,
+
+JVM `ParkEvent->unpark` 以及 JDK `LockSupport.unpark(this)` 底层同为 `pthread_cond_singal` 函数。
+
+
+
+WaitSet
+
+N1(T1)
+
+
+
+自旋锁(Spin Lock)
+
+CLH 队列
+
+- 原生 - JVM ParkEvent(自旋)
+- 变种 - JDK AQS Node(阻塞)
+ - LockSupport#park()
+
+
+
+当前 Thread
+
+Part Event (CLH 队列)
+
+
+
+`jdk.internal.misc.Unsafe#park`:
+
+```java
+public final class Unsafe {
+
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ }
+
+ public native void park(boolean isAbsolute, long time)
+}
+
+```
+
+`hotspot/src/share/vm/prims/unsafe.cpp`:
+
+```c++
+UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
+ UnsafeWrapper("Unsafe_Park");
+ EventThreadPark event;
+...
+ JavaThreadParkedState jtps(thread, time != 0);
+ thread->parker()->park(isAbsolute != 0, time);
+...
+UNSAFE_END
+```
+
+实际执行的代码:`thread->parker()->park`, 当前线程关联的 `Parker` 对象(由 parker() 方法返回)
+
+
+
+结论:
+
+- `java.lang.Object#wait(long)`
+ - `JVM_MonitorWait`
+ - `ObjectSynchronizer::wait`
+ - `Self->_ParkEvent->park ()`
+ - `os::PlatformEvent::park()`
+ - OS `pthread_cond_wait`
+- `Unsafe#park(boolean,long)`
+ - JVM Native
+ - JVM `Parker::park`
+ - OS `pthread_cond_wait`
+- `Unsafe#unpark()`
+ - JVM Native
+ - JVM `Parker::unpark`
+ - OS `pthread_cond_singal`
+
+
+
+T1 park -> 释放锁
+
+T2 获得锁 -> park
+
+T3 获得锁
+
+
+
+T main -> T1.unpark
+
+
+
+
+
+
+
+
+
+- 中止 - `Thread#interrupt()`
+- 休眠 - `Thread#sleep(long)`
+- 让出 - `Thread#yield()`
+- 停止 - ~~Thread#stop()~~
+
+
+
+
+
+### JNI 接口定义
+
+
+
+
+
+
+
+
+
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/Synchronization - Christian Wimmer - 2008.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/Synchronization - Christian Wimmer - 2008.pdf"
new file mode 100644
index 0000000..4b14ca7
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/Synchronization - Christian Wimmer - 2008.pdf" differ
diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\345\233\233\350\212\202\343\200\212JVM \345\271\266\345\217\221\345\256\236\347\216\260\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\345\233\233\350\212\202\343\200\212JVM \345\271\266\345\217\221\345\256\236\347\216\260\343\200\213.pdf"
new file mode 100644
index 0000000..d94e575
Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\345\233\233\346\234\237/\347\254\254\345\233\233\350\212\202 JVM \345\271\266\345\217\221\345\256\236\347\216\260/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\345\233\233\346\234\237 \347\254\254\345\233\233\350\212\202\343\200\212JVM \345\271\266\345\217\221\345\256\236\347\216\260\343\200\213.pdf" differ