顺序输出模型:
package ao.com;
//2比1先输出
public class Test01 {
//锁对象
private static Object lock = new Object();
//先输出完了的标志。
private 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();
}
}
System.out.println("1");
}
},"t1");
Thread t2 = new Thread(()->{
synchronized (lock) {
System.out.println("2");
//打印完了后要把标志位设置成后面位置需要的样子。然后唤醒这些线程。
t2Runned = true;
lock.notify();
}
},"t2");
t1.start();
t2.start();
}
}
交替输出模型
package ao.com;
//交替打印abc。。
//整体思路:创建一个对象,对象中的方法实现打印效果,而打印方法是同步的,
//根据传入的参数不同,打印不同的字符串,方法中就实现信号对应,如果条件满足就打印并且唤醒其他等待线程,不满足就阻塞等待
public class Test02 {
public static void main(String[] args) {
//因为第一个要是a,a的对应信号flag是1,第二个参数是循环次数。打印多少遍
waitNotify waitNotify = new waitNotify(1,5);
Thread t1 = new Thread(()->{
try {//线程拿到锁的时候,对比这个对象中的flag标志位是不是和传入的一样,只有一样的才打印并且修改flag进入下一个字符的打印。
waitNotify.print("a",1,2);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
Thread t2 = new Thread(()->{
try {
waitNotify.print("b",2,3);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t2");
Thread t3 = new Thread(()->{
try {
waitNotify.print("c",3,1);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
t1.start();
t2.start();
t3.start();
}
}
class waitNotify{
//a的标志是1,b的标志是2,c的标志是3
private int flag;
//循环次数。
private int loopNumber;
public waitNotify(int flag,int loopNumber){
this.flag = flag;
this.loopNumber = loopNumber;
}
public void print(String s,int printFlag,int nextFlag) throws InterruptedException {
int i = 0;
while (i++ < loopNumber){
//互斥锁,得按照顺序来,满足条件才打印并且更新flag,不满足就进入阻塞。三个线程共享一个实例对象.
synchronized (this){
while (printFlag != flag){
this.wait();
}
System.out.print(s);
flag = nextFlag;
this.notifyAll();
}
}
}
}