1195. Alternate print string

Posted by nemxu on Mon, 20 Jan 2020 10:27:30 +0100

Catalog

1. With a semaphore, in unrelated concurrency, you can use the semaphore as a flowing lock. It's better to use atomicinterger similar to cas spin

Write a program that can output a string representing this number from 1 to n, but:

If the number can be divided by three, output "fizz".
If the number can be divided by 5, output "buzz".
If the number can be divided by 3 and 5 at the same time, output "fizzbuzz".
For example, when n = 15, output: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizz.

Suppose there is a class:

class FizzBuzz {
public FizzBuzz(int n) { ... } // constructor
public 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
}
Please implement a multi-threaded version of FizzBuzz with four threads. The same FizzBuzz instance will be used by the following four threads:

Thread A will call fizz() to determine whether it can be divided by 3. If it can, it will output fizz.
Thread B will call buzz() to determine whether it can be divided by 5. If it can, it will output buzz.
Thread C will call fizzbuzz() to determine whether it can be divided by 3 and 5 at the same time. If it can, it will output fizzbuzz.
Thread D will call number() to implement a number whose output cannot be divisible by either 3 or 5.

Source: LeetCode
Link: https://leetcode-cn.com/problems/fizz-buzz-multithreaded
Copyright belongs to the network. For commercial reprint, please contact the official authorization. For non-commercial reprint, please indicate the source.

class FizzBuzz {
	private int n;
	private volatile int count = 1;//You can use Atomicteger here to ensure correctness
	private Semaphore semaphore = new Semaphore(1);


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

	// printFizz.run() outputs "fizz".
	public void fizz(Runnable printFizz) throws InterruptedException {
		while (true) {
			try {
				semaphore.acquire();
				if (count > n) {
					return;
				}
				if (count % 3 == 0 && count % 5 != 0) {
					printFizz.run();
					count++;
				}
			} finally {
				semaphore.release();
			}
		}
	}

	// printBuzz.run() outputs "buzz".
	public void buzz(Runnable printBuzz) throws InterruptedException {
		while (true) {
			try {
				semaphore.acquire();
				if (count > n) {
					return;
				}
				if (count % 5 == 0 && count % 3 != 0) {
					printBuzz.run();
					count++;
				}
			} finally {
				semaphore.release();
			}

		}
	}

	// printFizzBuzz.run() outputs "fizzbuzz".
	public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
		while (true) {
			try {
				semaphore.acquire();
				if (count > n) {
					return;
				}
				if (count % 3 == 0 && count % 5 == 0) {
					printFizzBuzz.run();
					count++;
				}
			} finally {
				semaphore.release();
			}

		}
	}

	// printNumber.accept(x) outputs "x", where x is an integer.
	public void number(IntConsumer printNumber) throws InterruptedException {
        while (true) {
            try {
                semaphore.acquire();
                if (count > n) {
                    return;
                }
                if (count % 3 != 0&& count % 5 != 0) {
                    printNumber.accept(count);
                    count++;
                }
            } finally {
                semaphore.release();
            }

        }
	}
}
Published 23 original articles, won praise 4, visited 638
Private letter follow

Topics: network