顺序输出
park-unpark版
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true) {
//try { Thread.sleep(1000); } catch (InterruptedException e) { }
// 当没有许可时,当前线程暂停运行;有许可时,用掉这个许可,当前线程恢复运行
LockSupport.park();
System.out.println("1");
}
});
Thread t2 = new Thread(() -> {
while (true) {
System.out.println("2");
// 给线程 t1 发放『许可』(多次连续调用 unpark 只会发放一个『许可』)
LockSupport.unpark(t1);
try { Thread.sleep(500); } catch (InterruptedException e) { }
}
});
t1.start();
t2.start();
}
wait-notify版
static final Object lock = new Object();
// 标记 t2 是否运行过
static boolean t2runned = false;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
while (!t2runned) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
sout("1");
}
}, "t1");
Thread t2 = new Thraed(() -> {
synchronized (lock) {
sout("2");
t2runned = true;
lock.notify();
}
}, "t2");
t1.start();
t2.start();
}
交替输出
ReentrantLock版
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Demo04 {
public static void main(String[] args) throws InterruptedException {
AwaitSignal awaitSignal = new AwaitSignal(5);
Condition a = awaitSignal.newCondition();
Condition b = awaitSignal.newCondition();
Condition c = awaitSignal.newCondition();
new Thread(() -> {
awaitSignal.print("a", a, b);
}).start();
new Thread(() -> {
awaitSignal.print("b", b, c);
}).start();
new Thread(() -> {
awaitSignal.print("c", c, a);
}).start();
Thread.sleep(1000);
awaitSignal.lock(); // 主线程获得锁,因为要操作锁的条件变量了
try {
System.out.println("开始 ...");
a.signal(); // 唤醒锁的条件变量a中的所有等待线程
} finally {
awaitSignal.unlock();
}
}
}
class AwaitSignal extends ReentrantLock {
private int loopNumber;
public AwaitSignal(int loopNumber) {
this.loopNumber = loopNumber;
}
/**
*
* @param str 要打印的内容
* @param current 线程等待时需被唤醒时的条件变量
* @param next 下一个需要被唤醒的线程所在的条件变量
*/
public void print(String str, Condition current, Condition next) {
for (int i = 0; i < loopNumber; i ++) {
lock();
try {
current.await(); // current条件变量休眠
System.out.println(str);
next.signal(); // 唤醒下一个条件变量中的线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
wait-notify版
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Demo03")
public class Demo03 {
public static void main(String[] args) {
WaitNotify waitNotify = new WaitNotify(1, 10);
new Thread(() -> {
waitNotify.print("a", 1, 2);
}).start();
new Thread(() -> {
waitNotify.print("b", 2, 3);
}).start();
new Thread(() -> {
waitNotify.print("c", 3, 1);
}).start();
}
}
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;
}
}
park-unpark版
import java.util.concurrent.locks.LockSupport;
public class Demo05 {
static Thread t1;
static Thread t2;
static Thread t3;
public static void main(String[] args) {
ParkUnpark pu = new ParkUnpark(5);
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();
LockSupport.unpark(t1);
}
}
class ParkUnpark {
public void print(String str, Thread next) {
for (int i = 0; i < loopNumber; i ++) {
LockSupport.park();
System.out.println(str);
LockSupport.unpark(next);
}
}
private int loopNumber;
public ParkUnpark(int loopNumber) {
this.loopNumber = loopNumber;
}
}