双线程交替打印奇偶数

如何使用两个线程交替打印奇偶数?

这是一道经典的面试题,与生产消费者模型类似,都是在使用锁控制两个线程的线程安全问题。

先看代码:

public class OddEvenPrinter {

    private final Object monitor = new Object();
    private final int limit;
    private volatile int count;

    public OddEvenPrinter(int limit, int initCount) {
        this.limit = limit;
        this.count = initCount;
    }

    public void print() {
        synchronized (monitor) {
            while (count < limit) {
                try {
                    System.out.println(String.format("线程[%s]打印数字:%d", Thread.currentThread().getName(), ++count));
                    monitor.notify();
                    if (count < limit) {
                        monitor.wait();
                    } 
                    
                } catch (InterruptedException e) {
                    //ignore
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        OddEvenPrinter printer = new OddEvenPrinter(100, 0);
        Thread thread1 = new Thread(printer::print, "thread-1");
        Thread thread2 = new Thread(printer::print, "thread-2");
        thread1.start();
        thread2.start();
    }
}

代码不长,主要启动两个线程然后开始打印数字,这里面有两个重点的 API,也是现学的, 分别是 notify 和 wait。

monitor.notify() 会通知某一个在等待 monitor 对象锁的线程,准备获取锁然后执行代码。直到当前线程执行 monitor.wait() 或者执行完成,另一个线程就能继续执行了。

当然正常情况下一个线程进入了 synchronized (monitor) 代码段,直到走出 synchronized 否则别的线程是获取不到 monitor 对象锁的。而 monitor.wait() 会释放 monitor 锁,所以与 monitor.notify() 配合使用,就能切换当前执行的线程,从而实现交替打印奇偶数。

by 费城的二鹏 2020.07.24 长春

你可能感兴趣的:(双线程交替打印奇偶数)