文章目录
1 固定运行顺序
比如,必须先2后1打印
1.1 wait notify 版
public class waitNotify {
static final Object lock = new Object();
//表示t2是否运行过
static boolean t2runned = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (lock){
while(!t2runned){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("1");
},"t1");
Thread t2 = new Thread(() -> {
synchronized (lock){
System.out.println("2");
t2runned = true;
lock.notify();
}
},"t2");
t1.start();
TimeUnit.SECONDS.sleep(5);
t2.start();
}
}
1.2 Park Unpark 版
public class parkUnpark {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
LockSupport.park();
System.out.println("1");
});
t1.start();
TimeUnit.SECONDS.sleep(3);
Thread t2 = new Thread(() -> {
System.out.println("2");
LockSupport.unpark(t1);
});
t2.start();
}
}
2 交替输出
线程1输出 a 5次,线程2输出 b 5次,线程 c 5次。现在要求输出abcabcabcabcabc怎么实现
2.1 wait notify 版
public class AlternateOutput {
public static void main(String[] args) {
WaitNotify wn = new WaitNotify(1,5);
new Thread(() -> {
wn.print("a",1,2);
}).start();
new Thread(() -> {
wn.print("b",2,3);
}).start();
new Thread(() -> {
wn.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 final int loopNumber;
public WaitNotify(int flag, int loopNumber) {
this.flag = flag;
this.loopNumber = loopNumber;
}
}
2.2 Lock 条件变量版
public class AlternateOutput_awaitSignal {
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();
}finally {
awaitSignal.unlock();
}
}
}
class AwaitSignal extends ReentrantLock {
private int loopNumber;
public AwaitSignal(int loopNumber){
this.loopNumber = loopNumber;
}
public void print(String str,Condition current,Condition next){
for (int i = 0; i < loopNumber; i++) {
lock();
try {
current.await();
System.out.print(str);
next.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
unlock();
}
}
}
}
2.3 Park Unpark 版
public class AlternateOutput_parkUnpark {
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;
}
}