题目地址:Fizz Buzz Multithreaded - LeetCode


Write a program that outputs the string representation of numbers from 1 to n, however:

If the number is divisible by 3, output “fizz”.
If the number is divisible by 5, output “buzz”.
If the number is divisible by both 3 and 5, output “fizzbuzz”.
For example, for n = 15, we output: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz.

Suppose you are given the following code:

class FizzBuzz {public FizzBuzz(int n) { ... }               // constructorpublic void fizz(printFizz) { ... }          // only output "fizz"public void buzz(printBuzz) { ... }          // only output "buzz"public void fizzbuzz(printFizzBuzz) { ... }  // only output "fizzbuzz"public void number(printNumber) { ... }      // only output the numbers
}

Implement a multithreaded version of FizzBuzz with four threads. The same instance of FizzBuzz will be passed to four different threads:

Thread A will call fizz() to check for divisibility of 3 and outputs fizz.
Thread B will call buzz() to check for divisibility of 5 and outputs buzz.
Thread C will call fizzbuzz() to check for divisibility of 3 and 5 and outputs fizzbuzz.
Thread D will call number() which should only output the numbers.


这道题目是LeetCode的并发系列题目,题目意思也很简单,4个线程分别做不同的事情,难的点是需要4个线程都完成任务后都进行等待。

总结一下任务过程:

1.调用4个函数,然后等待

2.4个函数调用都完成后,n+1.

3.如果一个函数重复调用,可以选择阻塞线程,或者直接跳过。

既然提到多线程的任务同步,很容易想到Java线程库中的CountDownLatchCyclicBarrier

先介绍一下:

CountDownLatch 主要用来解决一个线程等待多个线程的场景,可以类比旅游团团长要等待所有的游客到齐才能去下一个景点;而 CyclicBarrier 是一组线程之间互相等待,更像是几个驴友之间不离不弃。除此之外 CountDownLatch 的计数器是不能循环利用的,也就是说一旦计数器减到 0,再有线程调用 await(),该线程会直接通过。但 CyclicBarrier 的计数器是可以循环利用的,而且具备自动重置的功能,一旦计数器减到 0 会自动重置到你设置的初始值。除此之外,CyclicBarrier 还可以设置回调函数,可以说是功能丰富。

但这道题目的难点在于4个线程要相互等待,而且一个函数可能被重复调用,等4个函数都执行完成后才能对n进行操作。

在思考后我觉得还是一个函数直接完成循环知道完成任务更容易实现。

Java解法如下:


class FizzBuzz {private int n;private int currentNumber = 1;private final Object mutex = new Object();public FizzBuzz(int n) {this.n = n;}// printFizz.run() outputs "fizz".public void fizz(Runnable printFizz) throws InterruptedException {synchronized (mutex) {while (currentNumber <= n) {if (currentNumber % 3 != 0 || currentNumber % 5 == 0) {mutex.wait();continue;}printFizz.run();currentNumber += 1;mutex.notifyAll();}}}// printBuzz.run() outputs "buzz".public void buzz(Runnable printBuzz) throws InterruptedException {synchronized (mutex) {while (currentNumber <= n) {if (currentNumber % 5 != 0 || currentNumber % 3 == 0) {mutex.wait();continue;}printBuzz.run();currentNumber += 1;mutex.notifyAll();}}}// printFizzBuzz.run() outputs "fizzbuzz".public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {synchronized (mutex) {while (currentNumber <= n) {if (currentNumber % 15 != 0) {mutex.wait();continue;}printFizzBuzz.run();currentNumber += 1;mutex.notifyAll();}}}// printNumber.accept(x) outputs "x", where x is an integer.public void number(IntConsumer printNumber) throws InterruptedException {synchronized (mutex) {while (currentNumber <= n) {if (currentNumber % 3 == 0 || currentNumber % 5 == 0) {mutex.wait();continue;}printNumber.accept(currentNumber);currentNumber += 1;mutex.notifyAll();}}}
}

这里用了锁解决并发问题,但如果想要不用锁,循环轮询等待的话,可以使用AtomicInteger

LeetCode 1195. Fizz Buzz Multithreaded--并发系列题目--Java 解法--AtomicInteger/CountDownLatch/CyclicBarrier相关推荐

  1. LeetCode之Fizz Buzz

    1.题目 Write a program that outputs the string representation of numbers from 1 to n. But for multiple ...

  2. LeetCode 动态规划(Dynamic programming)系列题目--C++,Python解法

    LeetCode上有许多态规划(Dynamic programming)的题目,我在这里整合一下 本文章不再更新,请看LeetCode 所有题目总结 LeetCode 所有题目总结:LeetCode ...

  3. leetcode 412. Fizz Buzz

    Write a program that outputs the string representation of numbers from 1 to n. But for multiples of ...

  4. [LeetCode] Binary Tree Paths - 二叉树基础系列题目

    目录: 1.Binary Tree Paths - 求二叉树路径 2.Same Tree - 判断二叉树相等 3.Symmetric Tree - 判断二叉树对称镜像 Binary Tree Path ...

  5. java 实现队列读写锁_史上最全的Java并发系列之Java中的锁的使用和实现介绍(二)...

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger 种一棵树最好的时间是十年前,其次是现在 絮叨 上节是锁的第一 ...

  6. java中的原子操作_[Java并发系列] 2.Java中的原子操作类

    1. 原子操作类的作用 当程序更新一个变量时,如果多个线程同时更新该变量,可能会得到期望以外的值.比如i=1, 线程A更新i+1, 同时线程B更新I+1,经过两个线程的操作,最终变量i的值可能不是3, ...

  7. 【java并发系列】java多线程实现生产者消费者模式

    大家好,我是walker 一个从文科自学转行的程序员~ 爱好编程,偶尔写写编程文章和生活 欢迎关注公众号[I am Walker],回复"电子书",就可以获得200多本编程相关电子 ...

  8. LeetCode 77. Combinations--回溯法,-Python,Java解法

    题目地址: Given two integers n and k, return all possible combinations of k numbers out of 1 - n. Exampl ...

  9. LeetCode412_412. Fizz Buzz

    LeetCode412_412. Fizz Buzz 一.描述 给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果, ...

最新文章

  1. iOS之UI--转场动画
  2. 移动端1px像素的设置?
  3. poj 3398 (树上的最小支配集)
  4. 海拨3000点位的岛型堰塞湖
  5. Delta3d框架学习--程序启动过程详解
  6. c语言逗号占几个字符,C语言 scanf输入多个数字只能以逗号分隔的操作
  7. 聚类算法_案例实战:聚类实战
  8. mysql基础知识(一)
  9. android之数组排序
  10. 【NOIP2017】宝藏
  11. C#实现微信扫码支付
  12. 【2021中国华录杯·数据湖算法大赛】火热进行中,丰厚大赛奖金等你来拿!
  13. 《Python助力交通》公众号说明
  14. 叉乘点乘混合运算公式_《3D数学基础》提炼总结(四)向量运算(后)
  15. 脚本之家电子书下载:https://www.jb51.net/books/
  16. Android开发酒店预定预约管理系统
  17. 双一次算法作业hhhhhhhhh
  18. gtest之断言宏的使用以及三种事件机制
  19. cad能整体比例缩小吗_cad怎么把原尺寸图缩小几倍
  20. java中的高内聚和低耦合和接口的简单理解

热门文章

  1. PennyLane | 用于量子计算机可微分编程的跨平台Python库
  2. RDKit:运用RDKit计算USRCAT
  3. Wiley-中国科学院文献情报中心开放科学联合研讨会第一讲:开放科学全球和中国发展态势...
  4. Cell封面:王二涛组在丛枝菌根共生“自我调节”研究中取得重大进展(视频+漫画解读)...
  5. 连续发表三篇NAR的数据库文章——数据库承建
  6. 未来到底是什么样子?
  7. SEL:世界土壤日Stefan Geisen报告(朱永官院士主持,12月4日)
  8. 公益合种樟子松/新树专车3天领证
  9. R语言ggplot2可视化:可视化水平堆叠条形图(horizontal stacked bar plot)并在条形图中的每个分组条形区域显示区域占整体的百分比数值标签
  10. R语言使用magick包的image_border函数和image_background函数自定义图像的边界和背景(Change image border and background)