Skip to content

Commit 0887f4f

Browse files
committed
docs: 运行了 03concurrency/0301 中的示例,并添加了自己的一些理解注释
1 parent 6943786 commit 0887f4f

34 files changed

Lines changed: 303 additions & 230 deletions

03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ public class DaemonThread {
44

55
public static void main(String[] args) throws InterruptedException {
66
Runnable task = () -> {
7-
try {
8-
Thread.sleep(5000);
7+
try {
8+
Thread.sleep(5000);
99
} catch (InterruptedException e) {
1010
e.printStackTrace();
1111
}
12-
Thread t = Thread.currentThread();
13-
System.out.println("当前线程:" + t.getName());
12+
Thread t = Thread.currentThread();
13+
System.out.println("当前线程:" + t.getName());
1414
};
1515
Thread thread = new Thread(task);
1616
thread.setName("test-thread-1");
17+
18+
// 设置新线程为守护线程,当主线程退出时,若只剩下守护线程,JVM 会直接结束该进程
19+
// 因此新线程可能还没执行完就结束了,解决方法如下
20+
// 方法一:不设置新线程为守护线程,方法二:休眠主线程几秒,为新线程预留一点执行时间
1721
thread.setDaemon(true);
1822
thread.start();
1923

03concurrency/0301/src/main/java/java0/conc0301/op/Join.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33
public class Join {
44

55
public static void main(String[] args) {
6+
// 初始化 Object 类对象 oo,后面作为 synchronized 修饰的对象
67
Object oo = new Object();
7-
8+
9+
// 初始化一个新的线程对象
810
MyThread thread1 = new MyThread("thread1 -- ");
911
//oo = thread1;
12+
13+
// 将 oo 赋值到线程属性 Object 对象中,确保 run 方法中锁的对象和主线程是同一个
1014
thread1.setOo(oo);
1115
thread1.start();
12-
13-
synchronized (oo) { // 这里用oo或thread1/this
16+
17+
// 使用 oo 作为锁的对象,确保和新线程中 run 方法时同一个对象,使得两个线程需要争抢锁,保证线程安全
18+
// 还可以将 oo 改成 thread1,新线程 run 方法中改为 this,达到同样的目的
19+
synchronized (oo) {
1420
for (int i = 0; i < 100; i++) {
1521
if (i == 20) {
1622
try {

03concurrency/0301/src/main/java/java0/conc0301/sync/TestSetGet.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@ public class TestSetGet {
55
public static void main(String[] args) throws Exception {
66

77
final SetGet s = new SetGet();
8-
Thread t = new Thread(){
9-
@Override
10-
public void run() {
11-
try {
12-
s.get();
13-
} catch (Exception e) {
14-
e.printStackTrace();
15-
}
8+
Thread t = new Thread(() -> {
9+
try {
10+
s.get();
11+
} catch (Exception e) {
12+
e.printStackTrace();
1613
}
17-
};
14+
});
1815
t.start();
1916
long start = System.currentTimeMillis();
17+
18+
// 主线程调用了 SetGet 类对象的 set 方法,该方法通过 synchronized 修饰
19+
// 又因为新线程调用的 SetGet 类对象 get 方法,也通过 synchronized 修饰
20+
// 并且主线程和新线程都作用于同一个对象 s,因此会与新线程争抢锁
2021
s.set(10);
2122
System.out.println(" ... " + ( System.currentTimeMillis() - start ));
2223

@@ -26,16 +27,22 @@ public void run() {
2627
public static class SetGet {
2728

2829
int a = 0;
30+
31+
/**
32+
* set 和 get 方法都使用了 synchronized 修饰
33+
* 当两个不同的线程,对同一个SetGet类对象,同一时间,分别调用了set和get,也需要争抢锁
34+
* 这个时候 synchronized 的锁对象就是 SetGet 类对象,等价于 synchronized (this) {}
35+
*/
2936
public synchronized void set(int v) throws Exception {
3037
System.out.println(Thread.currentThread().getName() +" setting " +v);
31-
Thread.sleep(1000);
38+
Thread.sleep(5000);
3239
a = v;
3340
System.out.println(Thread.currentThread().getName() +" set " +v);
3441
}
3542

3643
public synchronized int get() throws Exception {
3744
System.out.println(Thread.currentThread().getName() +" getting ");
38-
Thread.sleep(10000);
45+
Thread.sleep(1000);
3946
System.out.println(Thread.currentThread().getName() + " get ");
4047
return a;
4148
}

03concurrency/0301/src/main/java/java0/conc0301/sync/Thread2.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,8 @@ public synchronized void m4t2() {
2929

3030
public static void main(String[] args) {
3131
final Thread2 myt2 = new Thread2();
32-
Thread t1 = new Thread(new Runnable() {
33-
public void run() {
34-
myt2.m4t1();
35-
}
36-
}, "t1");
37-
Thread t2 = new Thread(new Runnable() {
38-
public void run() {
39-
myt2.m4t2();
40-
}
41-
}, "t2");
32+
Thread t1 = new Thread(() -> myt2.m4t1(), "t1");
33+
Thread t2 = new Thread(() -> myt2.m4t2(), "t2");
4234
t2.start();
4335
t1.start();
4436
}

03concurrency/0301/src/main/java/java0/conc0301/sync/Thread3.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,22 @@ private void m4t2() {
2727
}
2828

2929
private void m4t1(Inner inner) {
30-
synchronized (inner) { //使用对象锁
30+
// 使用对象锁
31+
synchronized (inner) {
3132
inner.m4t1();
3233
}
3334
}
3435

3536
private void m4t2(Inner inner) {
37+
// m4t2 方法没有使用对象锁,因此可以让其他线程并行执行该方法
3638
inner.m4t2();
3739
}
3840

3941
public static void main(String[] args) {
4042
final Thread3 myt3 = new Thread3();
4143
final Inner inner = myt3.new Inner();
42-
Thread t1 = new Thread(new Runnable() {
43-
public void run() {
44-
myt3.m4t1(inner);
45-
}
46-
}, "t1");
47-
Thread t2 = new Thread(new Runnable() {
48-
public void run() {
49-
myt3.m4t2(inner);
50-
}
51-
}, "t2");
44+
Thread t1 = new Thread(() -> myt3.m4t1(inner), "t1");
45+
Thread t2 = new Thread(() -> myt3.m4t2(inner), "t2");
5246
t1.start();
5347
t2.start();
5448
}

03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@ public class AtomicMain {
55

66
public static void main(String[] args) {
77
final SyncCount count = new SyncCount();
8-
for (int i = 0; i < 100; i++) {
9-
new Thread(new Runnable() {
10-
@Override
11-
public void run() {
12-
for (int j = 0; j < 10000; j++) {
13-
count.add();
14-
}
8+
for (int i = 0; i < 10; i++) {
9+
new Thread(() -> {
10+
for (int j = 0; j < 10000; j++) {
11+
count.add();
1512
}
1613
}).start();
1714
}

03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@ public static void main(String[] args) {
1010
final AtomicLong atomicLong = new AtomicLong();
1111
final LongAdder longAdder = new LongAdder();
1212

13-
for (int i = 0; i < 100; i++) {
14-
new Thread(new Runnable() {
15-
@Override
16-
public void run() {
17-
for (int j = 0; j < 10000; j++) {
18-
atomicLong.getAndIncrement();
19-
longAdder.increment();
20-
}
13+
for (int i = 0; i < 10; i++) {
14+
new Thread(() -> {
15+
for (int j = 0; j < 10000; j++) {
16+
atomicLong.getAndIncrement();
17+
longAdder.increment();
2118
}
2219
}).start();
2320
}

03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ public class SyncCount {
1010

1111
private Lock lock = new ReentrantLock(true);
1212

13+
/**
14+
* 显示的使用 Lock 来加锁和解锁
15+
*/
1316
public int add() {
1417
try {
1518
lock.lock();

03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ public ChangeObjectThread(String name) {
1515
@Override public void run() {
1616
synchronized (u) {
1717
System.out.println("in " + getName());
18+
/*
19+
无限期挂起当前执行线程,最常见的唤醒方法有两种:
20+
- 其它线程调用了 unpark 方法,参数为被挂起的线程
21+
- 其它线程中断了被挂起的线程
22+
*/
1823
LockSupport.park();
1924
if (Thread.currentThread().isInterrupted()) {
20-
System.out.println("被中断了");
25+
System.out.println(getName() + "被中断了");
2126
}
22-
System.out.println("继续执行");
27+
System.out.println(getName() + "继续执行");
2328
}
2429
}
2530
}
@@ -29,8 +34,11 @@ public static void main(String[] args) throws InterruptedException {
2934
Thread.sleep(1000L);
3035
t2.start();
3136
Thread.sleep(3000L);
37+
// 中断被挂起的线程 t1,让它继续执行后面的逻辑
3238
t1.interrupt();
39+
// 主线程调用 unpark 方法,唤醒被挂起的线程 t2
3340
LockSupport.unpark(t2);
41+
// 主线程等待 t1,t2 线程执行完毕
3442
t1.join();
3543
t2.join();
3644
}

03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantLockDemo.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,16 @@ public void run() {
2222
}.start();
2323
}
2424
}
25+
26+
/*
27+
Thread-0 get begin
28+
Thread-0 get end
29+
Thread-1 get begin
30+
Thread-1 get end
31+
Thread-2 put begin
32+
Thread-2 put end
33+
Thread-3 put begin
34+
Thread-3 put end
35+
读互斥、写互斥,都需要争抢锁
36+
*/
2537
}

0 commit comments

Comments
 (0)