要求
创建3个线程,按照顺序分别打印”A”、”B”、”C”,循环n次
方法一:wait-notify
package com.huangbei.test1;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.LockSupport;
@Slf4j(topic = "c.Test-线程顺序执行")
public class Test2 {
public static void main(String[] args) {
//创建三个线程
WaitNotify wn = new WaitNotify(1, 10);
new Thread(() -> {
wn.print("A", 1, 2);
}).start();
new Thread(() -> {
wn.print("B", 2, 3);
}).start();
new Thread(() -> {
wn.print("C", 3, 1);
}).start();
}
}
@Slf4j(topic = "c.WaitNotify")
class WaitNotify {
//设置一个等待变量
private int flag;
//循环次数
private int loopN;
WaitNotify(int initialFlag, int loopN) {
this.flag = initialFlag;
this.loopN = loopN;
}
public void print(String content, int waitFlag, int nextFlag) {
for (int i = 0; i < loopN; i++) {
synchronized (this) {
while (flag != waitFlag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.debug("{}", content);
flag = nextFlag;
//记得要唤醒等待的线程
notifyAll();
}
}
}
}
方法二:wait-signal
package com.huangbei.test1;
import com.huangbei.util.Sleeper;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.Test-线程顺序执行")
public class Test3 {
public static void main(String[] args) {
AwaitSignal as = new AwaitSignal(10);
Condition c1 = as.newCondition();
Condition c2 = as.newCondition();
Condition c3 = as.newCondition();
new Thread(() -> {
as.print("A", c1, c2);
}).start();
new Thread(() -> {
as.print("B", c2, c3);
}).start();
new Thread(() -> {
as.print("C", c3, c1);
}).start();
//主线程1s后唤醒第一个线程
Sleeper.sleep(1);
try {
as.lock();
c1.signal();
} finally {
as.unlock();
}
}
}
@Slf4j(topic = "c.AwaitSignal")
class AwaitSignal extends ReentrantLock {
private int loopN;
AwaitSignal(int loopN) {
this.loopN = loopN;
}
public void print(String content, Condition current, Condition next) {
for (int i = 0; i < loopN; i++) {
try {
this.lock();
try {
current.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("{}", content);
//叫醒下一个线程
next.signal();
} finally {
this.unlock();
}
}
}
}
方法三:park&unpark
package com.huangbei.test1;
import com.huangbei.util.Sleeper;
import com.sun.org.apache.bcel.internal.generic.LoadClass;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.Test-线程顺序执行")
public class Test4 {
static Thread t1,t2,t3;
public static void main(String[] args) {
ParkUnpark pu = new ParkUnpark(10);
t1 = new Thread(() -> {
pu.print("A", t2);
});
t2 = new Thread(() -> {
pu.print("B", t3);
});
t3 = new Thread(() -> {
pu.print("C", t1);
});
t1.start();
t2.start();
t3.start();
Sleeper.sleep(1);
LockSupport.unpark(t1);
}
}
@Slf4j(topic = "c.park-unpark")
class ParkUnpark {
private int loopN;
ParkUnpark(int loopNumber) {
this.loopN = loopNumber;
}
public void print(String content, Thread next) {
for (int i = 0; i < loopN; i++) {
LockSupport.park();
log.debug("{}", content);
LockSupport.unpark(next);
}
}
}