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

时间:2019-07-08 17:38:09

标签: java concurrency semaphore

我想使用4个线程和信号量来实现I0708 13:06:27.614871 18173 solver.cpp:289] Solving I0708 13:06:27.614881 18173 solver.cpp:290] Learning Rate Policy: fixed I0708 13:06:27.615998 18173 solver.cpp:347] Iteration 0, Testing net (#0) I0708 13:06:27.616011 18173 net.cpp:676] Ignoring source layer data F0708 13:06:27.791405 18173 blob.hpp:140] Check failed: num_axes() <= 4 (5 vs. 4) Cannot use legacy accessors on Blobs with > 4 axes. *** Check failure stack 游戏。
我设法使线程按期望的顺序工作:$this->resultRepository->add($newResult);
但是,我无法使整个过程循环化。
每个方法都有其自己的信号量,尽管在释放下一个方法信号量之前就已锁定了它自己的信号量,但这些方法并不挂在第二个获取上(实际上,这是方法中的第一个)。

所需的行为:
1.锁定所有信号灯。
2.启动所有4种方法。
3.释放FizzBizz信号量,使其优先。
4. fizz() -> buzz() -> fizzBuzz() -> printNumber()完成,释放fizz()锁定并挂起,直到fizz()释放。
5.等。

buzz()

1 个答案:

答案 0 :(得分:0)

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

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
...
相关问题