同步设计模式之顺序控制(控制线程的运行次序)
一个案例:两个线程t1和t2,t1打印1,t2打印2,要求必须先打印2在打印1
- wait-notify
@Slf4j(topic = "c.Test25")
public class Test25 {
static final Object lock = new Object();
static boolean twoIsPrinted = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (lock) {
while (!twoIsPrinted) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.debug("1");
}
}, "t1");
Thread t2 = new Thread(() -> {
synchronized (lock) {
log.debug("2");
twoIsPrinted = true;
lock.notify();
}
}, "t2");
t1.start();
Thread.sleep(1000);
t2.start();
}
}
- ReentrantLock中的condition的await和signal
public class Test25 {
static final ReentrantLock lock = new ReentrantLock();
static final Condition condition = lock.newCondition();
static boolean twoIsPrinted = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
lock.lock();
try {
while (!twoIsPrinted) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.debug("1");
}finally {
lock.unlock();
}
}, "t1");
Thread t2 = new Thread(() -> {
lock.lock();
try {
log.debug("2");
twoIsPrinted = true;
condition.signal();
}finally {
lock.unlock();
}
}, "t2");
t1.start();
Thread.sleep(1000);
t2.start();
}
}
- park和unpark
@Slf4j(topic = "c.Test25")
public class Test25 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
LockSupport.park();
log.debug("1");
}, "t1");
Thread t2 = new Thread(() -> {
log.debug("2");
LockSupport.unpark(t1);
}, "t2");
t1.start();
t2.start();
}
}
另一个案例:线程1输出a五次,线程2输出b五次,线程3输出c五次,要求输出形式为:abcabcabcabcabc交替输出
- wait-notify
public class Test27 {
public static void main(String[] args) {
WaitNotify waitNotify = new WaitNotify(1, 5);
Thread t1 = new Thread(() -> {
waitNotify.print("a",1,2);
}, "t1");
Thread t2 = new Thread(() -> {
waitNotify.print("b",2,3);
}, "t2");
Thread t3 = new Thread(() -> {
waitNotify.print("c",3,1);
}, "t3");
t1.start();
t2.start();
t3.start();
}
}
/*
输出内容 等待标记 下一个标记
a 1 2
b 2 3
c 3 1
*/
class WaitNotify {
//打印
public void print(String str, int waitFlag, int nextFlag) {
for (int i = 0; i < loopnumber; i++) {
synchronized (this) {
while (flag != waitFlag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(str);
flag = nextFlag;
this.notifyAll();
}
}
}
//等待标记
private int flag;
//循环次数
private int loopnumber;
public WaitNotify(int flag, int loopnumber) {
this.flag = flag;
this.loopnumber = loopnumber;
}
}
- await-signall
@Slf4j(topic = "c.Test27")
public class Test27 {
public static void main(String[] args) throws InterruptedException {
AwaitSignal1 awaitsignal = new AwaitSignal1(5);
Condition condition1 = awaitsignal.newCondition();
Condition condition2 = awaitsignal.newCondition();
Condition condition3 = awaitsignal.newCondition();
new Thread(()->{
awaitsignal.print("a",condition1,condition2);
},"t1").start();
new Thread(()->{
awaitsignal.print("b",condition2,condition3);
},"t2").start();
new Thread(()->{
awaitsignal.print("c",condition3,condition1);
},"t3").start();
Thread.sleep(1000);
awaitsignal.lock();
try {
System.out.println("开始");
condition1.signal();
}finally {
awaitsignal.unlock();
}
}
}
/*
输出内容 等待标记 下一个标记
a 1 2
b 2 3
c 3 1
*/
class AwaitSignal1 extends ReentrantLock {
private int loopnumber;
public AwaitSignal1(int loopnumber) {
this.loopnumber = loopnumber;
}
//参数1 打印内容 参数2 进入哪个条件等待 参数3 唤醒哪个条件
public void print(String str, Condition current, Condition next) {
for (int i = 0; i < loopnumber; i++) {
lock();
try {
try {
current.await();
System.out.print(str);
next.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}finally {
unlock();
}
}
}
}
- park和unpark
@Slf4j(topic = "c.Test31")
public class Test31 {
public static Thread t1;
public static Thread t2;
public static Thread t3;
public static void main(String[] args) {
ParkUnPark parkUnPark = new ParkUnPark(5);
t1 = new Thread(() -> {
parkUnPark.print("a",t2);
}, "t1");
t2 = new Thread(() -> {
parkUnPark.print("b",t3);
}, "t2");
t3 = new Thread(() -> {
parkUnPark.print("c",t1);
}, "t3");
t1.start();
t2.start();
t3.start();
LockSupport.unpark(t1);
}
}
class ParkUnPark {
private int loopnumber;
public ParkUnPark(int loopnumber) {
this.loopnumber = loopnumber;
}
public void print(String str, Thread next) {
for (int i = 0; i < loopnumber; i++) {
LockSupport.park();
System.out.print(str);
LockSupport.unpark(next);
}
}
}