两线程交替打印数字

定义两个线程 交替打印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());
}
}
posted @ 2019-02-14 00:28  Sciluo  阅读(1687)  评论(0编辑  收藏  举报