'Is my multi-threaded "fizz buzz" implementation thread safe?
For educational purposes I am implementing classical "fizz buzz" problem using multiple threads.
"fizz buzz" game is:
The player designated to go first says the number "1", and each player thenceforth counts one number in turn. However, any number divisible by three is replaced by the word fizz and any divisible by five by the word buzz. Numbers divisible by both become fizz buzz
In my implementation I have 4 threads:
- First thread prints number if it is not multiple of 3 or 5 and increment current counter.
- Second thread prints “fizz”...
- Third thread prints “buzz”...
- Forth thread prints “fizz buzz”...
I don't use any locking and thread synchronizations mechanisms. Is my multi-threaded "fizz buzz" implementation thread safe? And, if not, why? I added comments in code of implementation for "suspicious" places.
My Implementation:
package threads;
import java.util.function.IntFunction;
public class FizzBuzzGameRunner {
// not volatile
// if other thread updates currentNum and current thread will see old (cached) value
// nothing bad can happen, just burn some CPU cycles uselessly
private int currentNum = 1;
public static void main(String... args) throws InterruptedException {
FizzBuzzGameRunner fizzBuzzGame = new FizzBuzzGameRunner();
startAll(
fizzBuzzGame.createRunnable(n -> (n % 3 != 0 && n % 5 != 0) ? String.valueOf(n) : null),
fizzBuzzGame.createRunnable(n -> (n % 3 == 0 && n % 5 != 0) ? "fizz" : null),
fizzBuzzGame.createRunnable(n -> (n % 3 != 0 && n % 5 == 0) ? "buzz" : null),
fizzBuzzGame.createRunnable(n -> (n % 3 == 0 && n % 5 == 0) ? "fizz buzz" : null)
);
Thread.sleep(1000);
}
private static void startAll(Runnable... workers) {
for (Runnable w : workers) {
Thread t = new Thread(w);
t.setDaemon(true);
t.start();
}
}
private Runnable createRunnable(IntFunction<String> singleStep) {
return () -> {
while (true) {
int currNum = this.currentNum;
// no synchronization
String result = singleStep.apply(currNum);
if (result != null) {
//Even without synchronization this block will be
//executed maximum by single thread simultaneously.
//Because each thread increments this.currentNum as part of that action,
//but no other thread will increment for the same value.
System.out.println(result);
this.currentNum++;
}
}
};
}
}
I understand that my example is totally artificial. To implement multi-threaded "Fizz Buzz" algorithm inspired one famous book for preparation for "codding interview". I just wanted to proof that example in book (which required to have 4 threads) can be solved without using synchronization and locks.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
