传送门:https://leetcode-cn.com/probl...
比较难懂。一个方法是一个线程,要保持四个线程的按序打印。吐槽一下还有这样写代码的...
将四个线程序列化
即将线程按照 fizz
- buzz
- fizzbuzz
- number
- fizz
……的顺序依次判断每个数字。将四个线程按序执行,实际上没有完成多线程。
public void fizz(Runnable printFizz) throws InterruptedException {
for(int i=1;i<=n;++i){
while(count!=0){
//System.out.println("wait0");
}
//System.out.println("unlock0");
if(i%3==0&&i%5!=0){
printFizz.run();
}
//将count置为1,让线程1执行
count=1;
}
}
public void buzz(Runnable printBuzz) throws InterruptedException {
for(int i=1;i<=n;++i){
while(count!=1){
//System.out.println("wait1");
}
//System.out.println("unlock1");
if(i%5==0&&i%3!=0){
printBuzz.run();
}
//将count置为2,让线程2执行
count=2;
}
}
很不幸结果超时了
输出阻塞 -- 误,应该是自旋
由于每个线程只对于特定的数字才有结果输出,则只需要在输出前判断当前是不是轮到这个数输出了。
下图所示:
fizz线程执行到3阻塞;buzz线程执行到5阻塞;fizzbuzz还未阻塞;num线程在1输出。可以直观的感受到并发所提升的效率。
fizz | buzz | fizzbuzz | num |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 2 | 2 | |
3 | 3 | 3 | |
4 | 4 | ||
5 | 5 | ||
6 |
public void fizz(Runnable printFizz) throws InterruptedException {
for(int i=1;i<=n;++i){
if(i%3==0&&i%5!=0){
while(count != i-1);
printFizz.run();
count = i;
}
}
}
public void buzz(Runnable printBuzz) throws InterruptedException {
for(int i=1;i<=n;++i){
if(i%5==0&&i%3!=0){
while(count != i-1);
printBuzz.run();
count = i;
}
}
}
按照序列化的方法,在while阻塞中加入Thread.yield();
可以通过。yield()方法暂停当前执行线程,将其回到可执行状态。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。