1、wait notify 版
public class SyncWaitNotify {
//打印标识:1打印a,2打印b,3打印c
private int flag;
//每个字母的打印次数
private int loopNumber;
//构造方法
public SyncWaitNotify(int flag, int loopNumber) {
this.flag = flag;
this.loopNumber = loopNumber;
}
public static void main(String[] args) {
SyncWaitNotify syncWaitNotify = new SyncWaitNotify(1, 5);
//打印a的线程
new Thread(() -> {
//打印a
syncWaitNotify.print(1, 2, "a");
}).start();
//打印b的线程
new Thread(() -> {
//打印b
syncWaitNotify.print(2, 3, "b");
}).start();
//打印c的线程
new Thread(() -> {
//打印c
syncWaitNotify.print(3, 1, "c");
}).start();
}
//根据参数打印不同的字母
/*
* waitFlag:根据这个参数打印对应的字母
* nextFlag:下一个要打印的字母对应的flag值
* str:要打印的字母
* */
public void print(int waitFlag, int nextFlag, String str) {
for (int i = 0; i < loopNumber; i++) {
//加锁
synchronized (this) {
//判断当前flag值是否和要打印的字母对应的flag值相等
while (this.flag != waitFlag) {
//不想等则让出cpu,等待其他线程执行
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//相等则打印
System.out.print(str);
//修改flag的值
flag = nextFlag;
//唤醒所有等待的线程
this.notifyAll();
}
}
}
}
2、Lock 条件变量版
public class AwaitSignal extends ReentrantLock {
// 循环次数
private int loopNumber;
public AwaitSignal(int loopNumber) {
this.loopNumber = loopNumber;
}
public void start(Condition first) {
this.lock();
try {
//唤醒打印a的线程
first.signal();
}
finally {
this.unlock();
}
}
public void print(String str, Condition current, Condition next) {
for (int i = 0; i < loopNumber; i++) {
//获得锁
this.lock();
try {
//进入等待
current.await();
//打印字母
System.out.println(str);
//唤醒下一个要打印的线程
next.signal();
}
catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放锁
this.unlock();
}
}
}
public static void main(String[] args) {
AwaitSignal as = new AwaitSignal(5);
//a的条件变量
Condition aWaitSet = as.newCondition();
//b的条件变量
Condition bWaitSet = as.newCondition();
//c的条件变量
Condition cWaitSet = as.newCondition();
//打印a的线程
new Thread(() -> {
as.print("a", aWaitSet, bWaitSet);
}).start();
//打印b的线程
new Thread(() -> {
as.print("b", bWaitSet, cWaitSet);
}).start();
//打印c的线程
new Thread(() -> {
as.print("c", cWaitSet, aWaitSet);
}).start();
//先让a线程获取锁,并唤醒a线程,否则所有线程都会进入等待
as.start(aWaitSet);
}
}