6.leetcode 多线程 1116. 打印零与奇偶数

假设有这么一个类:

class ZeroEvenOdd {
public ZeroEvenOdd(int n) { ... } // 构造函数
public void zero(printNumber) { ... } // 仅打印出 0
public void even(printNumber) { ... } // 仅打印出 偶数
public void odd(printNumber) { ... } // 仅打印出 奇数
}
相同的一个 ZeroEvenOdd 类实例将会传递给三个不同的线程:

线程 A 将调用 zero(),它只输出 0 。
线程 B 将调用 even(),它只输出偶数。
线程 C 将调用 odd(),它只输出奇数。
每个线程都有一个 printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列 010203040506... ,其中序列的长度必须为 2n。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/print-zero-even-odd
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。



class ZeroEvenOdd {
    private int n;
    
    private Semaphore zeroSema = new Semaphore(1);
    private Semaphore evenSema = new Semaphore(0);
    private Semaphore oddSema = new Semaphore(0);
    
    //记录当前应该打印奇数还是偶数
    private volatile int curNumber = 1;
    
    public ZeroEvenOdd(int n) {
        this.n = n;
    }
    // printNumber.accept(x) outputs "x", where x is an integer.
    public void zero(IntConsumer printNumber) throws InterruptedException {
        for (;;) {
            //尝试获取信号,否则一直自旋
            this.zeroSema.acquire(1);
            
            if (this.curNumber > n) {
                //给打印奇偶增加信号
                this.oddSema.release(1);
                this.evenSema.release(1);
                return;
            }
            
            printNumber.accept(0);        
            
            //根据记录的当前值,判断需要给奇偶的哪一个数据增加信号量
            if ((this.curNumber & 0x01) != 0) {
                this.oddSema.release(1); 
            } else {
                this.evenSema.release(1);
            }
        }
    }
    public void even(IntConsumer printNumber) throws InterruptedException {
        for(;;) {
            //尝试奇数消耗信号,否则自旋
            this.evenSema.acquire(1);
            
            if (this.curNumber > n) {
                return;
            }
            
            printNumber.accept(this.curNumber);
            this.curNumber++;
            //给偶数增加信号
            this.zeroSema.release(1);
        }
    }
    public void odd(IntConsumer printNumber) throws InterruptedException {
        for(;;) {
            this.oddSema.acquire(1);
            
            if (this.curNumber > n) {
                return;
            }
            
            printNumber.accept(this.curNumber);
            this.curNumber++;
            
            this.zeroSema.release(1);
        }
    }
}




你可能感兴趣的:(6.leetcode 多线程 1116. 打印零与奇偶数)