多线程交替打印
用两个线程,一个输出字母,一个输出数字,交替输出1A2B3C....26Z
# LockSupport.park() & LockSupport.unpark()
使用JUC包下的LockSupport,LockSupport.park()与LockSupport.unpark()都是调用Unsafe类内的本地方法,使用C或C++开发。
public class Main {
private static Thread numsThread;
private static Thread charThread;
public static void main(String[] args) {
char[] nums = "123456789".toCharArray();
char[] chars = "ABCDEFGHI".toCharArray();
numsThread = new Thread(()-> {
for (char num : nums) {
System.out.print(num);
LockSupport.unpark(charThread); // 唤醒 charThread
LockSupport.park(); // 将自己阻塞
}
},"numsThread");
charThread = new Thread(()-> {
for (char c : chars) {
LockSupport.park(); // 先将自己阻塞,等待charThread唤醒自己
System.out.print(c); // 打印
LockSupport.unpark(numsThread); // 任务完成,唤醒numsThread
}
},"charThread");
numsThread.start();
charThread.start();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# wait() & notifyAll()
使用Object.wait()和Object.notifyAll()或者Object.wait()和Object.notify(),它们的区别是notify()会随机唤醒一个线程。
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
char[] nums = "123456789".toCharArray();
char[] chars = "ABCDEFGHI".toCharArray();
new Thread(() -> {
synchronized (lock) {
for (char num : nums) {
try {
System.out.print(num); // 当前线程执行任务完成
lock.notifyAll(); // 唤醒所有线程
lock.wait(); // 当前线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "numsThread").start();
new Thread(() -> {
synchronized (lock) {
for (char c : chars) {
try {
System.out.print(c); // 打印
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "charThread").start();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Condition & ReentrantLock
JUC包下的Condition相当于一个等待队列,使用signal()唤醒等待队列内的线程或者await()将自己加入等待队列。
public class Main {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
char[] nums = "123456789".toCharArray();
char[] chars = "ABCDEFGHI".toCharArray();
Condition numsLock = lock.newCondition();
Condition charsLock = lock.newCondition();
new Thread(() -> {
lock.lock();
try {
for (char num : nums) {
System.out.print(num);
charsLock.signal(); // 叫醒‘等待队列2’
numsLock.await(); // 当前线程进入‘等待队列1’
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}, "numsThread").start();
new Thread(() -> {
lock.lock();
try {
for (char c : chars) {
System.out.print(c); // 打印
numsLock.signal(); // // 叫醒‘等待队列1’
charsLock.await(); // 当前线程进入‘等待队列2’
}
numsLock.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}, "charThread").start();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
上次更新: 2020/10/13, 13:10:00