题目链接:点击打开链接
题目大意:略。
解题思路:略。
相关企业
- 字节跳动
- 微软(Microsoft)
AC 代码
// 方法1:CyclicBarrier
class FizzBuzz {
private int n;
private CyclicBarrier cb = new CyclicBarrier(4);
public FizzBuzz(int n) {
this.n = n;
}
// printFizz.run() outputs "fizz".
public void fizz(Runnable printFizz) throws InterruptedException {
for (int i = 1; i <= n; i++) {
if (i % 3 == 0 && i % 5 != 0) {
printFizz.run();
}
try {
cb.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
// printBuzz.run() outputs "buzz".
public void buzz(Runnable printBuzz) throws InterruptedException {
for (int i = 1; i <= n; i++) {
if (i % 3 != 0 && i % 5 == 0) {
printBuzz.run();
}
try {
cb.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
// printFizzBuzz.run() outputs "fizzbuzz".
public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
for (int i = 1; i <= n; i++) {
if (i % 3 == 0 && i % 5 == 0) {
printFizzBuzz.run();
}
try {
cb.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void number(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i++) {
if (i % 3 != 0 && i % 5 != 0) {
printNumber.accept(i);
}
try {
cb.await();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
// 方法2:Semaphore
class FizzBuzz {
private int n;
private Semaphore number = new Semaphore(1);
private Semaphore fizz = new Semaphore(0);
private Semaphore buzz = new Semaphore(0);
private Semaphore fizzbuzz = new Semaphore(0);
public FizzBuzz(int n) {
this.n = n;
}
// printFizz.run() outputs "fizz".
public void fizz(Runnable printFizz) throws InterruptedException {
for (int i = 1; i <= n; i++) {
if (i % 3 == 0 && i % 5 != 0) {
fizz.acquire();
printFizz.run();
number.release();
}
}
}
// printBuzz.run() outputs "buzz".
public void buzz(Runnable printBuzz) throws InterruptedException {
for (int i = 1; i <= n; i++) {
if (i % 3 != 0 && i % 5 == 0) {
buzz.acquire();
printBuzz.run();
number.release();
}
}
}
// printFizzBuzz.run() outputs "fizzbuzz".
public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
for (int i = 1; i <= n; i++) {
if (i % 3 == 0 && i % 5 == 0) {
fizzbuzz.acquire();
printFizzBuzz.run();
number.release();
}
}
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void number(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i++) {
number.acquire();
if (i % 3 != 0 && i % 5 != 0) {//开始打印
printNumber.accept(i);
number.release();
} else if (i % 3 == 0 && i % 5 != 0) {//fizz开始打印
fizz.release();
} else if (i % 3 != 0 && i % 5 == 0) {//buzz开始打印
buzz.release();
} else {
fizzbuzz.release();//fizzbuzz开始打印
}
}
}
}
// 方法3:Semaphore
class FizzBuzz {
private int n;
private Semaphore semaphore = new Semaphore(1);
private int cur = 1;
public FizzBuzz(int n) {
this.n = n;
}
// printFizz.run() outputs "fizz".
public void fizz(Runnable printFizz) throws InterruptedException {
while (true) {
semaphore.acquire(1);
try {
// 原因就在这里,循环过程中如果打印的字符串个数已经满足要求,那么会使用return来返回,终止该方法的执行。
// 但是咱们已经获取了信号量,那么在方法返回前需要释放该信号量,否则会导致其它线程一直等待,整个程序一直不结束。
// Java语言中try-finally可以做到这一点,try-finally代码块也是常用的一种释放资源(IO流、数据库连接等)的方式。
// 不是程序死循环,而是其它线程在wait,导致无法退出。
if (cur > n) return;
if (cur % 3 == 0 && cur % 5 != 0) {
cur++;
printFizz.run();
}
} finally {
semaphore.release(1);
}
}
}
// printBuzz.run() outputs "buzz".
public void buzz(Runnable printBuzz) throws InterruptedException {
while (true) {
semaphore.acquire(1);
try {
if (cur > n) return;
if (cur % 3 != 0 && cur % 5 == 0) {
cur++;
printBuzz.run();
}
} finally {
semaphore.release(1);
}
}
}
// printFizzBuzz.run() outputs "fizzbuzz".
public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
while (true) {
semaphore.acquire(1);
try {
if (cur > n) return;
if (cur % 3 == 0 && cur % 5 == 0) {
cur++;
printFizzBuzz.run();
}
} finally {
semaphore.release(1);
}
}
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void number(IntConsumer printNumber) throws InterruptedException {
while (true) {
semaphore.acquire(1);
try {
if (cur > n) return;
if (cur % 3 != 0 && cur % 5 != 0) {
printNumber.accept(cur);
cur++;
}
} finally {
semaphore.release(1);
}
}
}
}
// 方法4:Thread.yield()
class FizzBuzz {
private int n;
private volatile int state = 0;
public FizzBuzz(int n) {
this.n = n;
}
public void fizz(Runnable printFizz) throws InterruptedException {
for (int i = 3; i <= n; i += 3) { //只输出3的倍数(不包含15的倍数)
if (i % 15 == 0) continue; //15的倍数不处理,交给fizzbuzz()方法处理
while (state != 3)
Thread.yield();
printFizz.run();
state = 0;
}
}
public void buzz(Runnable printBuzz) throws InterruptedException {
for (int i = 5; i <= n; i += 5) { //只输出5的倍数(不包含15的倍数)
if (i % 15 == 0) //15的倍数不处理,交给fizzbuzz()方法处理
continue;
while (state != 5)
Thread.yield();
printBuzz.run();
state = 0;
}
}
public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
for (int i = 15; i <= n; i += 15) { //只输出15的倍数
while (state != 15)
Thread.yield();
printFizzBuzz.run();
state = 0;
}
}
public void number(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; ++i) {
while (state != 0)
Thread.yield();
if (i % 3 != 0 && i % 5 != 0)
printNumber.accept(i);
else {
if (i % 15 == 0)
state = 15; //交给fizzbuzz()方法处理
else if (i % 5 == 0)
state = 5; //交给buzz()方法处理
else
state = 3; //交给fizz()方法处理
}
}
}
}
// 方法5:ReentrantLock+Condition
class FizzBuzz {
private int n;
private ReentrantLock lock = new ReentrantLock();
int state = 0;
private Condition condition = lock.newCondition();
public FizzBuzz(int n) {
this.n = n;
}
// printFizz.run() outputs "fizz".
public void fizz(Runnable printFizz) throws InterruptedException {
for (int i = 3; i <= n; i += 3) {
try {
if (i % 3 == 0 && i % 5 == 0) continue;
lock.lock();
while (state != 3) {
condition.await();
}
printFizz.run();
state = 0;
condition.signalAll();
} finally {
lock.unlock();
}
}
}
// printBuzz.run() outputs "buzz".
public void buzz(Runnable printBuzz) throws InterruptedException {
for (int i = 5; i <= n; i += 5) {
try {
if (i % 3 == 0 && i % 5 == 0) continue;
lock.lock();
while (state != 5) {
condition.await();
}
printBuzz.run();
state = 0;
condition.signalAll();
} finally {
lock.unlock();
}
}
}
// printFizzBuzz.run() outputs "fizzbuzz".
public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
for (int i = 15; i <= n; i += 15) {
try {
lock.lock();
while (state != 15) {
condition.await();
}
printFizzBuzz.run();
state = 0;
condition.signalAll();
} finally {
lock.unlock();
}
}
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void number(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i++) {
try {
lock.lock();
while (state != 0) {
condition.await();
}
if (i % 3 != 0 && i % 5 != 0) {
printNumber.accept(i);
} else {
if (i % 3 == 0 && i % 5 == 0) state = 15;
else if (i % 3 == 0) state = 3;
else if (i % 5 == 0) state = 5;
condition.signalAll();
}
} finally {
lock.unlock();
}
}
}
}
// 方法6:ReentrantLock+Condition
class FizzBuzz {
private int n;
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private int i = 1;
public FizzBuzz(int n) {
this.n = n;
}
// printFizz.run() outputs "fizz".
public void fizz(Runnable printFizz) throws InterruptedException {
while (true) {
try {
lock.lock();
if (i > n) {
return;
}
while (i % 3 != 0) {
condition.signalAll();
condition.await();
if (i > n) {
return;
}
}
printFizz.run();
i++;
} finally {
condition.signalAll();
lock.unlock();
}
}
}
// printBuzz.run() outputs "buzz".
public void buzz(Runnable printBuzz) throws InterruptedException {
while (true) {
try {
lock.lock();
if (i > n) {
return;
}
while (i % 5 != 0) {
condition.signalAll();
condition.await();
if (i > n) {
return;
}
}
printBuzz.run();
i++;
} finally {
condition.signalAll();
lock.unlock();
}
}
}
// printFizzBuzz.run() outputs "fizzbuzz".
public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
while (true) {
try {
lock.lock();
if (i > n) {
return;
}
while (!(i % 3 == 0 && i % 5 == 0)) {
condition.signalAll();
condition.await();
if (i > n) {
return;
}
}
printFizzBuzz.run();
i++;
} finally {
condition.signalAll();
lock.unlock();
}
}
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void number(IntConsumer printNumber) throws InterruptedException {
while (true) {
try {
lock.lock();
if (i > n) {
return;
}
while (i % 3 == 0 || i % 5 == 0) {
condition.signalAll();
condition.await();
if (i > n) {
return;
}
}
printNumber.accept(i);
i++;
} finally {
condition.signalAll();
lock.unlock();
}
}
}
}