线程间同步 - 轮流循环

写程序实现: 主线程循环5次接着子线程循环3次,接着再主线程循环5次子线程循环3次,如此反复3趟。

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package any;

/**
* 编写程序实现: 主线程循环5次接着子线程循环3次,接着再主线程循环5次子线程循环3次,
* 如此反复循环3趟。分析:(5+3)*3=24, 子线程在loop为24时主线程在loop为21时退出.
*/
class Looper implements Runnable {
private volatile int turnsCounter = 0; // 线程自己的连续循环次数
private volatile int loopsCounter = 0; // 总循环次数
// firstRunFlag, 以true代表第一个执行循环的线程, false代表第二个执行循环的线程
private volatile boolean frf;

public Looper(boolean frf){
this.frf = frf;
}

@Override
public void run() {
try {
loop(false); // 从子线程执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Sub thread finished.");
}

// 定义一个循环(里面的while)
public void loop(boolean isMainThread) throws InterruptedException {
synchronized (this) {
while (true) {
// 在一开始就检查是否轮到自己执行循环, 轮不到就等待
waitTurns(isMainThread);

// Working in loop ...
turnsCounter++;
System.out.println(
Thread.currentThread().getName()
+ ", loop turn: " + (loopsCounter + 1)
);

// 循环次数统计
loopsCounter++;

// 检查是否轮换循环以及是否可以停止自己的循环
if ((isMainThread && turnsCounter == 5) ||
(!isMainThread && turnsCounter == 3)
){
turnsCounter = 0;

// 注意takeTurns里面反转了frf, 所以没有抽到if之前
if ((frf && loopsCounter==21)||(!frf && loopsCounter == 24)){
takeTurns();
break; //跳出循环,退出临界区,再接下来打印后线程结束
} else {
takeTurns();
}
}
}
}
}

private void waitTurns(boolean t) throws InterruptedException {
while(t != this.frf){
this.wait();
}
}

private void takeTurns() {
this.frf = !this.frf;
this.notify(); //通知完成后在下一轮循环的waitTurns阻塞自己然后释放内部锁
}
}

public class Main {
public static void main(String[] args) throws InterruptedException {
Looper looper = new Looper(true);

new Thread(looper).start(); // 先启动子线程
looper.loop(true); // 主线程开始进入循环

System.out.println("Main thread finished.");
}
}

注:网上有些实现很复杂,写了上百行代码,而且是各自代码循环,并不是同一个Loop里面交替循环;另外没搞清楚子线程的概念,完全是两个并行线程,都是主线程的子线程,共三个线程,是不对的。

输出:

/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/bin/java ……
main, loop turn: 1
main, loop turn: 2
main, loop turn: 3
main, loop turn: 4
main, loop turn: 5
Thread-0, loop turn: 6
Thread-0, loop turn: 7
Thread-0, loop turn: 8
main, loop turn: 9
main, loop turn: 10
main, loop turn: 11
main, loop turn: 12
main, loop turn: 13
Thread-0, loop turn: 14
Thread-0, loop turn: 15
Thread-0, loop turn: 16
main, loop turn: 17
main, loop turn: 18
main, loop turn: 19
main, loop turn: 20
main, loop turn: 21
Main thread finished.
Thread-0, loop turn: 22
Thread-0, loop turn: 23
Thread-0, loop turn: 24
Sub thread finished.

Process finished with exit code 0

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×