春招打卡d8n13-leetcode刷题1195交替打印字符串

182 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

leetcode刷题1195交替打印字符串

前文

本文为leetcode多线程类型题目,题目序号为1195,主要考察多线程相关知识的应用。

题目信息

编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是:

如果这个数字可以被 3 整除,输出 "fizz"。 如果这个数字可以被 5 整除,输出 "buzz"。 如果这个数字可以同时被 3 和 5 整除,输出 "fizzbuzz"。 例如,当 n = 15,输出: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz。

解题思路

根据题目信息,当出现不同数字的时候我们要输出不同的答案。这里我们采用reentrantlock操作,采用四把锁进行操作,分别为四种打印信息。当满足条件时,则进行线程的执行。当不满足条件时,锁进入等待状态。锁在释放后要采用循环的方式等待锁信息的获取,主要是当其他线程释放锁时,能够保证当前线程能再次判断后执行,避免用if可能出现的问题。按照这种4把锁切换的方式,即可实现线程的字符串交替打印,满足题目的需求。

解题代码

class FizzBuzz {
    private int n;
    private int i = 1;
    private ReentrantLock lock = new ReentrantLock();
    private Condition fizzCon = lock.newCondition();
    private Condition buzzCon = lock.newCondition();
    private Condition fizzbuzzCon = lock.newCondition();
    private Condition numberCon = lock.newCondition();

    public FizzBuzz(int n) {
        this.n = n;
    }

    // printFizz.run() outputs "fizz".
    public void fizz(Runnable printFizz) throws InterruptedException {
        lock.lock();
        if(i % 3 != 0){
            fizzCon.await();
        }
        for (;i<=n;){
            printFizz.run();
            numberCon.signal();
            fizzCon.await();
        }
        lock.unlock();
    }

    // printBuzz.run() outputs "buzz".
    public void buzz(Runnable printBuzz) throws InterruptedException {
        lock.lock();
        if(i % 5 != 0){
            buzzCon.await();
        }
        for (;i<=n;){
            printBuzz.run();
            numberCon.signal();
            buzzCon.await();
        }
        lock.unlock();
    }

    // printFizzBuzz.run() outputs "fizzbuzz".
    public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
        lock.lock();
        if(i % 5 != 0 || i % 3 != 0){
            fizzbuzzCon.await();
        }
        for (;i<=n;){
            printFizzBuzz.run();
            numberCon.signal();
            fizzbuzzCon.await();
        }
        lock.unlock();
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void number(IntConsumer printNumber) throws InterruptedException {
        lock.lock();
        if(i <= n){
            for (;i<=n;i++) {
                if (i % 3 == 0 && i % 5 == 0) {
                    fizzbuzzCon.signal();
                    numberCon.await();
                } else if (i % 3 == 0) {
                    fizzCon.signal();
                    numberCon.await();
                } else if (i % 5 == 0) {
                    buzzCon.signal();
                    numberCon.await();
                } else {
                    printNumber.accept(i);
                }
            }
            //释放锁
            fizzCon.signal();
            buzzCon.signal();
            fizzbuzzCon.signal();
        }
        lock.unlock();
    }
}

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。