传送门:https://leetcode-cn.com/probl...
比较难懂。一个方法是一个线程,要保持四个线程的按序打印。吐槽一下还有这样写代码的...
将四个线程序列化
即将线程按照 fizz - buzz - fizzbuzz - number - fizz……的顺序依次判断每个数字。将四个线程按序执行,实际上没有完成多线程。

public void fizz(Runnable printFizz) throws InterruptedException {
        for(int i=1;i<=n;++i){
            while(count!=0){
                //System.out.println("wait0");
            }
            //System.out.println("unlock0");
            if(i%3==0&&i%5!=0){
                printFizz.run();
            }
            //将count置为1,让线程1执行
            count=1;
        }
    }
    
public void buzz(Runnable printBuzz) throws InterruptedException {
        for(int i=1;i<=n;++i){
            while(count!=1){
                //System.out.println("wait1");
            }
            //System.out.println("unlock1");
            if(i%5==0&&i%3!=0){
                printBuzz.run();
            }
            //将count置为2,让线程2执行
            count=2;
        }
    }

image.png
很不幸结果超时了

输出阻塞 -- 误,应该是自旋
由于每个线程只对于特定的数字才有结果输出,则只需要在输出前判断当前是不是轮到这个数输出了。
下图所示:
fizz线程执行到3阻塞;buzz线程执行到5阻塞;fizzbuzz还未阻塞;num线程在1输出。可以直观的感受到并发所提升的效率。

fizz buzz fizzbuzz num
1 1 1 1
2 2 2
3 3 3
4 4
5 5
6
public void fizz(Runnable printFizz) throws InterruptedException {
        for(int i=1;i<=n;++i){
            if(i%3==0&&i%5!=0){
                while(count != i-1);
                printFizz.run();
                count = i;
            }
        }
    }

public void buzz(Runnable printBuzz) throws InterruptedException {
        for(int i=1;i<=n;++i){
            if(i%5==0&&i%3!=0){
                while(count != i-1);
                printBuzz.run();
                count = i;
            }
        }
    }

image.png


按照序列化的方法,在while阻塞中加入Thread.yield();可以通过。yield()方法暂停当前执行线程,将其回到可执行状态。


HHXXHGGZ
0 声望0 粉丝

« 上一篇
Leetcode 449
下一篇 »
探究一下索引