Skip to content

Commit 5f524bf

Browse files
committed
Add Stage 3 Lesson 2
1 parent 12f678c commit 5f524bf

13 files changed

+279
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<name>「一入 Java 深似海 」系列 :: 第三期</name>
1414
<modules>
1515
<module>stage-3-lesson-1</module>
16+
<module>stage-3-lesson-2</module>
1617
</modules>
1718
<packaging>pom</packaging>
1819

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>stage-3</artifactId>
7+
<groupId>com.segmentfault</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>stage-3-lesson-2</artifactId>
13+
<name>「一入 Java 深似海 」系列 :: 第三期 :: 第二节</name>
14+
15+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
public class DeadLockDemo {
4+
5+
public static void main(String[] args) {
6+
7+
final Object m1 = new Object();
8+
final Object m2 = new Object();
9+
10+
new Thread(() -> {
11+
synchronized (m1) {
12+
System.out.printf("Thread[ ID : %d] holds m1\n", Thread.currentThread().getId());
13+
14+
synchronized (m2) {
15+
System.out.printf("Thread[ ID : %d] holds m2\n", Thread.currentThread().getId());
16+
}
17+
}
18+
}).start();
19+
20+
new Thread(() -> {
21+
synchronized (m2) {
22+
System.out.printf("Thread[ ID : %d] holds m2\n", Thread.currentThread().getId());
23+
24+
synchronized (m1) {
25+
System.out.printf("Thread[ ID : %d] holds m1\n", Thread.currentThread().getId());
26+
}
27+
}
28+
}).start();
29+
30+
31+
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.LinkedList;
4+
import java.util.List;
5+
import java.util.Random;
6+
import java.util.concurrent.ExecutionException;
7+
import java.util.concurrent.ExecutorService;
8+
import java.util.concurrent.Executors;
9+
import java.util.concurrent.Future;
10+
11+
public class ProducerConsumerProblemDemo {
12+
13+
public static void main(String[] args) throws ExecutionException, InterruptedException {
14+
15+
ExecutorService executorService = Executors.newFixedThreadPool(2);
16+
17+
Container container = new Container();
18+
19+
Future producerFuture = executorService.submit(() -> { // 生产者线程
20+
container.produce();
21+
});
22+
23+
Future consumerFuture = executorService.submit(() -> { // 消费者线程
24+
container.consume();
25+
});
26+
27+
28+
Thread.sleep(1000L);
29+
30+
executorService.shutdown();
31+
}
32+
33+
public static class Container {
34+
35+
private List<Integer> data = new LinkedList<>();
36+
37+
private static final int MAX_SIZE = 5;
38+
39+
private Random random = new Random();
40+
41+
public void produce() {
42+
while (true) { // 永久执行
43+
synchronized (this) {
44+
try {
45+
// 当数据超过上限 MAX_SIZE,停止生产
46+
while (data.size() >= MAX_SIZE) {
47+
wait();
48+
}
49+
int value = random.nextInt(100);
50+
System.out.printf("线程[%s] 正在生产数据 : %d\n", Thread.currentThread().getName(), value);
51+
data.add(value);
52+
53+
// 唤起消费线程
54+
notify();
55+
Thread.sleep(1000);
56+
} catch (InterruptedException e) {
57+
e.printStackTrace();
58+
}
59+
}
60+
}
61+
}
62+
63+
public void consume() {
64+
while (true) { // 永久执行
65+
synchronized (this) {
66+
try {
67+
// 当数据没有时,停止消费
68+
while (data.isEmpty()) {
69+
wait();
70+
}
71+
int value = data.remove(0);
72+
System.out.printf("线程[%s] 正在消费数据 : %d\n", Thread.currentThread().getName(), value);
73+
// 唤起消费线程
74+
notify();
75+
Thread.sleep(1000);
76+
} catch (InterruptedException e) {
77+
e.printStackTrace();
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
public class SynchronizedDemo {
4+
5+
public static void main(String[] args) {
6+
7+
synchronized (SynchronizedDemo.class) {
8+
9+
10+
}
11+
12+
new Thread().start();
13+
}
14+
15+
private static void changeValue(int value) {
16+
// 线程私有对象,尽管它也在堆里面
17+
// 栈保存 value 名称,data 变量名称
18+
// 堆共享(被其他线程可见)是线程不安全的,保存内存
19+
// 当线程不加以控制数量的话,容易导致 JVM OOM
20+
Data data = new Data();
21+
data.setValue(1);
22+
}
23+
24+
private static class Data {
25+
26+
/**
27+
* 线程不安全
28+
*/
29+
private volatile int value;
30+
31+
public int getValue() {
32+
return value;
33+
}
34+
35+
public void setValue(int value) {
36+
this.value = value;
37+
}
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
public class SynchronizedMethodAndBlockDemo {
4+
5+
public static void main(String[] args) {
6+
// synchronized 保证互斥
7+
// 当某个线程 T1 获得锁(1),重新又见到 synchronized(+1)
8+
// 以此类推
9+
echo("Hello,World"); // echo 到底重进入了多少次?3
10+
// echo -> PrintStream.println -> newLine()
11+
doEcho("Hello,World"); // doEcho 到底重进入了多少次?4
12+
// doEcho -> echo -> PrintStream.println -> newLine()
13+
}
14+
15+
private static void doEcho(String message) {
16+
Object object = new Object();
17+
synchronized (object) {
18+
// wait 和 notify
19+
echo(message);
20+
}
21+
}
22+
23+
/**
24+
* synchronized 修饰方法(实例或类)
25+
*
26+
* @param message
27+
*/
28+
private synchronized static void echo(String message) {
29+
System.out.println(message);
30+
}
31+
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
public class SynchronizedObjectAndClassDemo {
4+
5+
public static void main(String[] args) {
6+
7+
Object object = new Object();
8+
9+
// 对象锁
10+
synchronized (object) { // Monitor -> Object
11+
// 对象存在在 Heap(堆)
12+
// ...
13+
}
14+
15+
// 类锁
16+
synchronized (Object.class) {
17+
// 类对象存在于 Metadata区域(Java 8+)
18+
// 或者 Perm 区域(<= Java 7)方法区
19+
// ...
20+
}
21+
22+
// Class 对象就是 Object 实例
23+
Object objectClass = Object.class;
24+
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Vector;
6+
import java.util.function.Consumer;
7+
8+
public class SynchronizedPerformanceDemo {
9+
10+
public static void main(String[] args) {
11+
// 对比 Vector 和 ArrayList
12+
// 相同点:两者都使用数组(Array)作为存储,集合算法类似
13+
Vector vector = new Vector();
14+
ArrayList list = new ArrayList();
15+
16+
doTest(10000, vector);
17+
doTest(10000, list);
18+
19+
System.gc();
20+
21+
doTest(100000, vector);
22+
doTest(100000, list);
23+
24+
System.gc();
25+
26+
}
27+
28+
29+
private static void doTest(int count, List list) {
30+
long startTime = System.currentTimeMillis();
31+
for (int i = 0; i < count; i++) {
32+
list.add(new Object());
33+
}
34+
long costTime = System.currentTimeMillis() - startTime;
35+
System.out.printf("%s add costing %f ms(avg)\n", list.getClass().getName(), costTime / (count * 1.0));
36+
}
37+
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.segmentfault.deep.in.java.concurrency;
2+
3+
public class ThreadStarvationDemo {
4+
5+
public static void main(String[] args) {
6+
new ThreadStarvationDemo();
7+
}
8+
9+
public void finalize() { // FinalReference
10+
System.out.printf("Thread[%s] executes current object's finalization.\n", Thread.currentThread().getName());
11+
}
12+
}

0 commit comments

Comments
 (0)