Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中如何强制信号量中的顺序_Java_Concurrency - Fatal编程技术网

java中如何强制信号量中的顺序

java中如何强制信号量中的顺序,java,concurrency,Java,Concurrency,我使用信号量在程序中强制执行一些顺序:我有一个主线程和几个在主线程中创建的子线程。 在主线程中,每一步都会勾选一个时钟,然后我希望每个子线程逐一运行。子线程的顺序并不重要,但我希望它们都在每个步骤中运行(并且每个步骤只运行一次)。 我已经写了这段代码,但问题是在某些情况下,在一个步骤中,一个子线程会运行多次,而不让其他线程有机会运行 主线是: Semaphore okToTick = new Semaphore(3); Semaphore okToWork = new Sem

我使用信号量在程序中强制执行一些顺序:我有一个主线程和几个在主线程中创建的子线程。 在主线程中,每一步都会勾选一个时钟,然后我希望每个子线程逐一运行。子线程的顺序并不重要,但我希望它们都在每个步骤中运行(并且每个步骤只运行一次)。 我已经写了这段代码,但问题是在某些情况下,在一个步骤中,一个子线程会运行多次,而不让其他线程有机会运行

主线是:

     Semaphore okToTick = new Semaphore(3);
     Semaphore okToWork = new Semaphore(0, true);

     int i = 0;

     new TestClass2(0, okToTick, okToWork);
     new TestClass2(1, okToTick, okToWork);
     new TestClass2(2, okToTick, okToWork);

     while(true){

        okToTick.acquire(3);

        System.out.printf("\clock : %s\n", i++);


        okToWork.release(3);

     }
以及子线程的run()

    semaphores here, passed by cnstr() 
    ID = //passed in by cnstr()    
    isBusy = false; 
    ----------------------------------
    try{
        while(true){

            okToWork.acquire();

            if(!isBusy){
                System.out.println("inside sub " + ID);
                isBusy = true;
            }


            okToTick.release();

        }

    }
    catch(Exception e){}
我想要这个结果:

  clock : 0
  inside sub 1
  inside sub 0
  inside sub 2

  clock : 1

  clock : 2
  ...
但有时我会这样:

  clock : 0
  inside sub 1

  clock : 1
  inside sub 0
  inside sub 2

  clock : 2
  ...

我想你在找一个:

一种同步辅助工具,允许一组线程都等待对方到达一个共同的障碍点。CyclicBarrier在涉及固定大小的线程组的程序中很有用,这些线程有时必须互相等待。该屏障被称为循环屏障,因为它可以在释放等待的线程后重新使用


我想你在找一个:

一种同步辅助工具,允许一组线程都等待对方到达一个共同的障碍点。CyclicBarrier在涉及固定大小的线程组的程序中很有用,这些线程有时必须互相等待。该屏障被称为循环屏障,因为它可以在释放等待的线程后重新使用

问题是,您的“子线程”可能正在从信号量获取多个许可证,并且您在输出中没有意识到它,因为“内部子线程”输出只打印一次(如果删除(!isBusy)周围的
,您会多次看到它)。如果不希望每个“子线程”获取多个许可,请删除外部
while(true)
循环

    okToWork.acquire();

    //if(!isBusy){ Removed to show when this sub-thread is actually acquiring permits
        System.out.println("inside sub " + ID);
    //    isBusy = true;
    //}


    okToWork.release();
问题是,您的“子线程”可能正在从信号量获取多个许可证,并且您在输出中没有意识到它,因为“内部子线程”输出只打印一次(如果删除(!isBusy)
周围的
,您会多次看到它)。如果不希望每个“子线程”获取多个许可,请删除外部
while(true)
循环

    okToWork.acquire();

    //if(!isBusy){ Removed to show when this sub-thread is actually acquiring permits
        System.out.println("inside sub " + ID);
    //    isBusy = true;
    //}


    okToWork.release();

在您的情况下,一个线程可以在其他线程有机会启动之前获取
okToWork
并多次释放
okToTick
,即1号线程最多可以在其他线程之前执行3次
okToWork.acquire()
->
okToTick.release()

对于每个线程,您也只能在sub x内部打印一次
,因为您从不重置
isBusy
标志


你需要区分它们,使用
信号灯
最简单的方法就是给每个线程一个不同的
okToTick信号灯

在你的情况下,一个线程可以获得
okToWork
并在其他线程有机会启动之前多次释放
okToTick
,即线程1最多可以在其他线程之前执行3次
okTowork.acquire()
->
okToTick.release()

对于每个线程,您也只能在sub x内部打印一次
,因为您从不重置
isBusy
标志


您需要区分它们,使用
信号量
最简单的方法是为每个线程提供不同的
okToTick信号量。

我不熟悉这个主题。有没有可能只用信号灯就能完成这项工作?你用的是锤子来敲打螺丝。你为什么不学习如何使用螺丝刀呢。它有文档记录,我甚至链接到了javadoc。点击、阅读、理解并尝试一些东西。如果您只想使用信号量,我会在每个工作线程中使用一个信号量。您是对的,但我必须在明天之前完成。正如我对使用CyclicBarrier的理解,您必须使用实现runnable的类,但我不得不使用Thread的run方法。你能告诉我如何使用信号量来实现这个吗?每个工作线程使用一个信号量是什么意思?1)
CyclicBarrier
Runnable
无关;2)
公共类线程实现Runnable
我的意思是,可以让每个线程使用自己的信号量,而不是让所有线程使用单个信号量。我不熟悉这个主题。有没有可能只用信号灯就能完成这项工作?你用的是锤子来敲打螺丝。你为什么不学习如何使用螺丝刀呢。它有文档记录,我甚至链接到了javadoc。点击、阅读、理解并尝试一些东西。如果您只想使用信号量,我会在每个工作线程中使用一个信号量。您是对的,但我必须在明天之前完成。正如我对使用CyclicBarrier的理解,您必须使用实现runnable的类,但我不得不使用Thread的run方法。你能告诉我如何使用信号量来实现这个吗?每个工作线程使用一个信号量是什么意思?1)
CyclicBarrier
Runnable
无关;2)
公共类线程实现Runnable
我的意思是,您可以让每个线程使用自己的信号量,而不是让所有线程使用单个信号量。提示:当您释放okToTick时,时钟可能会滴答作响。而且,由于您在打印后立即发布它,所以有时时钟会立即滴答作响也就不足为奇了。您需要等待所有子线程完成,然后才能说可以勾选。祝你的家庭作业好运。如果你有要按特定顺序执行的任务,你应该在同一个线程中完成所有任务。当您有多个可以按任意顺序执行的独立任务时,多线程非常有用。提示:当您释放okToTick时,时钟可能会滴答作响。而且,由于您在打印后立即发布它,所以有时时钟会立即滴答作响也就不足为奇了。您需要等待所有子线程