两线程交替打印数字
定义两个线程 交替打印1~100的数,通过wait和notify实现
看到这个题目第一个想法是要控制两个线程交替打印 与生产者消费者的架构设计模式好像有点类似 所以直接上代码吧
public class alternateprint{ int i = 0; boolean isprintf = false; public void printf1() throws InterruptedException { while (i <= 100) { synchronized (this) { if (isprintf) { notifyAll(); System.out.println(Thread.currentThread().getName() + ":" + (i++)); isprintf = false; } else { wait(); } } } } public void printf2() throws InterruptedException { while (i <= 100) { synchronized (this) { if (!isprintf) { System.out.println(Thread.currentThread().getName() + ":" + (i++)); isprintf = true; notifyAll(); } else { wait(); } } } } public static void main(String[] args) { alternateprint alternateprint = new alternateprint(); new Thread() { @Override public void run() { try { alternateprint.printf1(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); new Thread() { @Override public void run() { try { alternateprint.printf2(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } }
逻辑单元很简单 通过wait和notify来控制逻辑的实现 一个线程在打印后即使再抢到cpu的执行权 也会因为isprintf的控制位而进入wait的状态,这样就实现了交替打印数字的任务,在写完看代码想到两个方法好像有点复杂,可以综合到一个方法中,毕竟主要的逻辑就是一个线程在输出后要进入wait状态由另一个线程输出后唤醒wait的线程,由此引出第二种写法如下:
public class printf {
int i = 0;
public synchronized void printf() throws InterruptedException {
while (i <= 100) {
notifyAll();
System.out.println(Thread.currentThread().getName() + ":" + (i++));
wait();
}
notifyAll();//这行若不添加jvm程序将会不退出,原因在于会有一个线程判断进入了wait状态,而另一个线程判断已经达到100了不会进入逻辑单元,导致另一个线程没线程唤醒 一直在wait中 所以在循环外添加一个notify唤醒它
}
public static void main(String[] args) {
printf pr = new printf();
IntStream.range(0, 2).forEach(i->new Thread(()->{
try {
pr.printf();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start());
}
}