gpt4 book ai didi

java - Java 中使用信号量的循环线程

转载 作者:行者123 更新时间:2023-12-02 03:19:00 25 4
gpt4 key购买 nike

我想使用 4 个线程和信号量来实现 FizzBizz 游戏。
我设法使线程按所需的顺序工作:fizz() ->uzz() -> fizzBu​​zz() -> printNumber()
但是,我无法设法使整个过程循环。
每个方法都有它自己的信号量,尽管在释放下一个方法信号量之前锁定了它自己的信号量,但这些方法只是不会卡在第二个获取上(实际上,这是方法中的第一个获取)。

期望的行为:
1. 锁定所有信号量。
2. 启动全部4个方法。
3. 释放fizz()信号量,使其先行。
4. fizz() 完成,释放 buzz() 锁并挂起,直到 printNumber() 释放它。
5.等等

import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicLong;

class FizzBuzz {
protected AtomicLong num = new AtomicLong(1);
protected AtomicLong n = new AtomicLong(100);
protected Semaphore sem1 = new Semaphore(1);
protected Semaphore sem2 = new Semaphore(1);
protected Semaphore sem3 = new Semaphore(1);
protected Semaphore sem4 = new Semaphore(1);

public void start() {
System.out.println("Started");
try {
sem1.acquire();
sem2.acquire();
sem3.acquire();
sem4.acquire();
this.fizz();
this.buzz();
this.fizzBuzz();
this.printNumber();
sem1.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public void fizz() {
new Thread() {
@Override
public void run() {
while (num.get() <= n.get()) {
try {
// System.out.println("Fizz waiting...");
sem1.acquire();
sem1.release();
if (num.get() > n.get()) {
break;
}
if (num.get() % 3 == 0 && num.get() % 5 != 0) {
num.getAndIncrement();
System.out.println("Fizz");
}
sem1.acquire();
sem2.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

public void buzz() {
new Thread() {
@Override
public void run() {
while (num.get() <= n.get()) {
try {
// System.out.println("Buzz waiting...");
sem2.acquire();
sem2.release();
if (num.get() > n.get()) {
break;
}
if (num.get() % 5 == 0 && num.get() % 3 != 0) {
num.getAndIncrement();
System.out.println("Buzz");
}
sem2.acquire();
sem3.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

public void fizzBuzz() {
new Thread() {
@Override
public void run() {
while (num.get() <= n.get()) {
try {
// System.out.println("FizzBuzz waiting...");
sem3.acquire();
sem3.release();
if (num.get() > n.get()) {
break;
}
if (num.get() % 3 == 0 && num.get() % 5 == 0) {
num.getAndIncrement();
System.out.println("FizzBuzz");
}
sem3.acquire();
sem4.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

public void printNumber() {
new Thread() {
@Override
public void run() {
while (num.get() <= n.get()) {
try {
// System.out.println("Print Number waiting...");
sem4.acquire();
sem4.release();
if (num.get() > n.get()) {
break;
}
if (num.get() % 3 == 1 && num.get() % 5 == 1) {
num.getAndIncrement();
System.out.println(num);
}
sem4.acquire();
sem1.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}

最佳答案

如果你坚持这种方式,我只是编写使用五个信号量的代码,因为四个信号量无法形成稳定的循环。

package exercise.concurrency;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class SemaphoreTest {
public static void main(String[] args) {
new FizzBuzz().start();
}

}




class FizzBuzz {
protected AtomicLong num = new AtomicLong(1);
protected AtomicLong n = new AtomicLong(100);
protected Semaphore sem1 = new Semaphore(1);
protected Semaphore sem2 = new Semaphore(1);
protected Semaphore sem3 = new Semaphore(1);
protected Semaphore sem4 = new Semaphore(1);
protected Semaphore sem5 = new Semaphore(1);

public void start() {
System.out.println("Started");
try {
sem1.acquire();
sem2.acquire();
sem3.acquire();
sem4.acquire();
sem5.acquire();
this.fizz();
this.buzz();
this.fizzBuzz();
this.printNumber();


} catch (Exception e) {
e.printStackTrace();
}
}

public void fizz() {
new Thread() {
@Override
public void run() {
sem1.release();
sem5.release();
while (num.get() <= n.get()) {
try {
sem1.acquire();
sem5.acquire();
if (num.get() > n.get()) {
break;
}
if (num.get() % 3 == 0 && num.get() % 5 != 0) {
num.getAndIncrement();
System.out.println("Fizz");
}
System.out.println("1.fizz one loop");
TimeUnit.MILLISECONDS.sleep(500);
sem2.release();
sem5.release();
Thread.yield();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("fizz has finshed");
}
}.start();
}

public void buzz() {
new Thread() {
@Override
public void run() {
while (num.get() <= n.get()) {
try {
sem2.acquire();
sem5.acquire();
if (num.get() > n.get()) {
break;
}
if (num.get() % 5 == 0 && num.get() % 3 != 0) {
num.getAndIncrement();
System.out.println("Buzz");
}
System.out.println("2.buzz one loop");
TimeUnit.MILLISECONDS.sleep(500);
sem3.release();
sem5.release();
Thread.yield();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
}

public void fizzBuzz() {
new Thread() {
@Override
public void run() {
while (num.get() <= n.get()) {
try {
sem3.acquire();
sem5.acquire();
if (num.get() > n.get()) {
break;
}
if (num.get() % 3 == 0 && num.get() % 5 == 0) {
num.getAndIncrement();
System.out.println("FizzBuzz");
}
System.out.println("3.fizzBuzz one loop");
TimeUnit.MILLISECONDS.sleep(500);
sem4.release();
sem5.release();
Thread.yield();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
}

public void printNumber() {
new Thread() {
@Override
public void run() {
while (num.get() <= n.get()) {
try {
sem4.acquire();
sem5.acquire();
if (num.get() > n.get()) {
break;
}
if (num.get() % 3 == 1 && num.get() % 5 == 1) {
num.getAndIncrement();
System.out.println(num);
}
System.out.println("4.printNumber one loop\n");
TimeUnit.MILLISECONDS.sleep(500);
sem1.release();
sem5.release();
Thread.yield();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
}
}

它使用 Thread.yield() 为线程引擎提供建议,当一个线程执行一次另一个线程有机会执行其工作时。TimeUnit.Millseconds.sleep() 使结果看起来清晰。

结果如下所示:

Started
1.fizz one loop
2.buzz one loop
3.fizzBuzz one loop
2
4.printNumber one loop

1.fizz one loop
2.buzz one loop
3.fizzBuzz one loop
4.printNumber one loop

1.fizz one loop
2.buzz one loop
3.fizzBuzz one loop
4.printNumber one loop

1.fizz one loop
2.buzz one loop
3.fizzBuzz one loop
4.printNumber one loop

1.fizz one loop
2.buzz one loop
3.fizzBuzz one loop
4.printNumber one loop

1.fizz one loop
...

关于java - Java 中使用信号量的循环线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56940005/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com