Skip to content

Instantly share code, notes, and snippets.

@alllex
Created July 10, 2023 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alllex/2eb9a01c99560dfa8674d1ef5a4fd830 to your computer and use it in GitHub Desktop.
Save alllex/2eb9a01c99560dfa8674d1ef5a4fd830 to your computer and use it in GitHub Desktop.
import java.util.concurrent.atomic.AtomicInteger
import kotlin.concurrent.thread
class FizzBuzzRace(private val n: Int) {
private enum class Owner { Fizz, Buzz, FizzBuzz, Num }
private val state = AtomicInteger(1)
private fun getOwner(k: Int) = when {
k % 3 == 0 && k % 5 == 0 -> Owner.FizzBuzz
k % 3 == 0 -> Owner.Fizz
k % 5 == 0 -> Owner.Buzz
else -> Owner.Num
}
fun fizz(printFizz: () -> Unit) = worker(Owner.Fizz) { printFizz() }
fun buzz(printBuzz: () -> Unit) = worker(Owner.Buzz) { printBuzz() }
fun fizzbuzz(printFizzBuzz: () -> Unit) = worker(Owner.FizzBuzz) { printFizzBuzz() }
fun number(printNumber: (Int) -> Unit) = worker(Owner.Num) { printNumber(it) }
private fun worker(owner: Owner, print: (Int) -> Unit) {
var last = 0L
var i = 0L
while (true) {
i++
val current = state.get()
if (current > n) return
if (getOwner(current) == owner) {
print(current)
state.incrementAndGet()
println("Thread ${Thread.currentThread().name} took ${i - last} iterations to print $current")
last = i
}
}
}
}
fun printFizz() = println("[${Thread.currentThread().name}] fizz")
fun printBuzz() = println("[${Thread.currentThread().name}] buzz")
fun printFizzBuzz() = println("[${Thread.currentThread().name}] fizzbuzz")
fun printNumber(x: Int) = println("[${Thread.currentThread().name}] $x")
fun main() {
val fizzBuzzRace = FizzBuzzRace(15)
val threads = listOf(
thread(start = false, name = "fizz") { fizzBuzzRace.fizz(::printFizz) },
thread(start = false, name = "buzz") { fizzBuzzRace.buzz(::printBuzz) },
thread(start = false, name = "fizzbuzz") { fizzBuzzRace.fizzbuzz(::printFizzBuzz) },
thread(start = false, name = "number") { fizzBuzzRace.number(::printNumber) },
)
println("Starting threads...")
threads.shuffled().forEach(Thread::start)
threads.shuffled().forEach(Thread::join)
println("All threads finished")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment