Java 如何在不使用if-else、while、for等的情况下使用信号量

Java 如何在不使用if-else、while、for等的情况下使用信号量,java,multithreading,semaphore,Java,Multithreading,Semaphore,这是家庭作业,但我只是在寻找一个正确的方向(不是有人为我做我的工作) 我有四根线 它们各自在一个循环中打印出自己的数字:1、2、4和8 在主线程开始时,我必须启动所有四个线程,然后在500毫秒后结束它们 我将使用信号量以确保只有这些数字以这种重复模式打印:11111111222224481111111122222448111112222448 我不能用while、for、if、else等等 我正在使用Java 我不知道如何在不使用if语句的情况下最终打印出该模式,而且我对信号量非常不熟悉,对

这是家庭作业,但我只是在寻找一个正确的方向(不是有人为我做我的工作)

  • 我有四根线
  • 它们各自在一个循环中打印出自己的数字:1、2、4和8
  • 在主线程开始时,我必须启动所有四个线程,然后在500毫秒后结束它们
  • 我将使用信号量以确保只有这些数字以这种重复模式打印:11111111222224481111111122222448111112222448
  • 我不能用while、for、if、else等等
  • 我正在使用Java
我不知道如何在不使用if语句的情况下最终打印出该模式,而且我对信号量非常不熟悉,对线程也只有一点熟悉

一个善良的灵魂能给我一些指引吗?即使你只是简单地给我指一段精彩的视频或文章,我也会很感激的


编辑:对不起。我把事情弄糊涂了。每个线程中已经为我定义了while语句。每个while语句一次只打印一个数字。例如:它打印的是“1”而不是“11111”。这是因为我不允许再定义while语句之类的语句。

如果您使用的是Java的信号量,那么我假设对acquire()的调用被阻塞了。因此,考虑到这一点,如果一个线程试图获取另一个线程已经获取的信号量,那么它必须等待,直到它可以自由地获取

每个模式都需要一个信号量。第一个线程应初始化为1(因为您希望该线程运行),所有其他线程应初始化为0(因为您希望首先阻止这些线程)

每个线程都应该从减少其信号量的值开始(如果信号量的值为0,则该调用将被阻塞)。在线程1的末尾,您应该增加第二个信号量的值。在线程2的末尾,您应该增加第三个信号量的值,依此类推。在最后一个线程结束时,您应该再次增加第一个信号量的值,以重新开始

因为我不想做你的家庭作业,所以我将给出一个只有两个线程的示例:

public static void main(String[] args) {
    final Semaphore thread1Block = new Semaphore(1);
    final Semaphore thread2Block = new Semaphore(0);

    Thread thread1 = new Thread(new Runnable() {
        public void run() {
            while (true) {
                // reduce the value of the first semaphore by one
                // blocking if the value is 0
                thread1Block.aquire();

                System.out.print("11111111");

                // increase the value of the second semaphore by one
                thread2Block.release();
            }
        }
    });

    Thread thread2 = new Thread(new Runnable() {
        public void run() {
            while (true) {
                // reduce the value of the second semaphore by one
                // blocking if the value is 0
                thread2Block.aquire();

                System.out.print("2222");

                // increase the value of the first semaphore by one
                thread1Block.release();
            }
        }
    });

    // start the threads
    thread1.start();
    thread2.start();
}
编辑

我显然误解了这个问题。棘手的部分是使用信号量作为计数器。我将按照以下方式进行操作(同样,仅以2个线程为例):


诀窍是每个信号量也用作计数器:只有当第一个信号量的值为0时,第二个信号量的值才会增加4。类似地,当第二个信号量的值为0时,第一个信号量的值将递增8。

如何在不使用循环的情况下生成重复模式?I second Heuster的语句。没有某种循环构造,任何语言都无法重复任何内容。线程的run方法将像其他方法一样直接运行,除非其中有某种循环。嗯,只需运行500毫秒。可能是大量的块复制/粘贴?非常愚蠢,是的,但在这样的问题之后…:)我会让一个线程打印所有的数字,而让其他三个线程什么也不做。是否可以让线程递归,直到主方法中的线程被终止?不过,这可能会使堆栈溢出。根据OP的说法,因为他不能使用
for
循环来生成打印语句,而且线程必须以特定的顺序运行(因此您无法轻松编写一个可重用的线程类,而不会变得太复杂),所以我认为这个答案是最好的。更清楚地说,我的线程中已经有一个while循环,一次只打印出其中一个数字。我的问题是,我如何知道它何时打印出了足够的1或2。@这就是我对这个问题的误解。我添加了我认为是正确的解决方案。这是正确的,但我想我主要关心的是如何让它运行while语句一定次数(1的情况下为8次),然后告诉它转到2,如果这样做有意义的话。我得到的代码看起来与@Heuster非常相似,只是我的while语句不是每次迭代都打印“11111111”,而是打印“1”。
public static void main(String[] args) {
    final Semaphore s1 = new Semaphore(8);
    final Semaphore s2 = new Semaphore(0);

    Thread t1 = new Thread(new Runnable() {
        public void run() {
            while (true) {
                s1.acquire();
                System.out.print("1");
                s2.release(4 * ((8 - s1.availablePermits()) / 8));
            }
        }
    });

    Thread t2 = new Thread(new Runnable() {
        public void run() {
            while (true) {
                s2.acquire();                   
                System.out.print("2");
                s1.release(8 * ((4 - s2.availablePermits()) / 4));
            }
        }
    });

    t1.start();
    t2.start();
}