LeetCode(多线程)- 1195. 交替打印字符串
Posted 程序员牧码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode(多线程)- 1195. 交替打印字符串相关的知识,希望对你有一定的参考价值。
题目链接:点击打开链接
题目大意:略。
解题思路:略。
相关企业
- 字节跳动
- 微软(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();
以上是关于LeetCode(多线程)- 1195. 交替打印字符串的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
LeetCode 多线程练习1(1114. 按序打印 / 1115. 交替打印FooBar)