使用信号量在java中实现cyclicbarrier
问题如下,因为屏障仅使用down()调用,因此它将等待n个线程到达,然后在关键区域一起执行所有n个线程,现在我如何通知调用barrier.down的线程它现在可以继续。我尝试在phase2()之后添加notifyAll(),但没有效果。帮助?:)使用信号量在java中实现cyclicbarrier,java,multithreading,semaphore,cyclicbarrier,Java,Multithreading,Semaphore,Cyclicbarrier,问题如下,因为屏障仅使用down()调用,因此它将等待n个线程到达,然后在关键区域一起执行所有n个线程,现在我如何通知调用barrier.down的线程它现在可以继续。我尝试在phase2()之后添加notifyAll(),但没有效果。帮助?:) 公共类自行车运载器{ 私人int n; 私人整数计数; 专用信号量互斥; 私人信号机旋转门; 私人信号机旋转栅门2; 公共自行车承运人(国际北){ 这个,n=n; 此值为0.count; this.mutex=新信号量(1); this.turnsti
公共类自行车运载器{
私人int n;
私人整数计数;
专用信号量互斥;
私人信号机旋转门;
私人信号机旋转栅门2;
公共自行车承运人(国际北){
这个,n=n;
此值为0.count;
this.mutex=新信号量(1);
this.turnstile=新信号灯(0);
this.turnstile2=新信号灯(0);
}
public synchronized void down()引发InterruptedException{
this.phase1();//等待n个线程到达
this.phase2();//等待n个线程执行
}
private synchronized void phase1()引发InterruptedException{
this.mutex.down();
这个.count++;
if(this.count==this.n){
for(int i=0;i0){
这个计数器=数字;
}
}
公共同步无效信号(){
这个.counter++;
notifyAll();
}
public synchronized void down()引发InterruptedException{
虽然(this.counter我看到您使用的是来自的解决方案。这本书的一个要点是,您可以使用信号量作为唯一的协调原语来解决许多协调问题。使用synchronized来实现信号量是非常好的,因为这是正确执行该操作所必需的。但是,使用它没有抓住要点在解决本应使用信号量解决的难题的方法中进行了同步
此外,我认为它在您的情况下不起作用:您在this.turnstile.down()处没有死锁吗?您阻塞了一个信号量,该信号量持有对象和方法上的独占锁(通过synchronized),从而允许释放该信号量
如前所述解决问题:您向线程发出信号,表示它们可以从barrier.down()返回。通过执行turnstile.down()确保不会过早返回
旁白:信号量实现
你的信号量实现看起来是正确的,只是你只允许非负的初始值,这至少是非标准的。这样做有什么动机,我看不出来吗?如果你认为负的初始值是错误的,为什么不抛出一个错误,而不是默默地做其他事情呢
旁白:其他同步原语
请注意,java构造synchronized、.wait()和.notify()对应于协调原语。使用监视器(或其他协调原语)解决谜题可能很有帮助而不是信号量,但我建议将这些努力分开。我在尝试使用解决一个难题时感到有点乐趣
旁白:关于可运行性
您说您已经尝试了一些东西,这表明您有一些代码可以让您运行问题中的代码。如果您包含了这些代码,那么我们也可以轻松地运行它,这会很有帮助。我可能会检查我假设的死锁是否真的发生。我不应该使用内置的cyclicBarrier:)是的,还有信号量:)我讨厌使用notifyAll()吗
当只有一个线程被释放时。我假设你不能使用原子整数和朋友?我不知道原子整数是什么…我应该绑定两个氢线程和一个氧线程。也就是说,每两个氢线程在屏障上等待一个氧线程到达,然后所有线程都被执行。我已经跟踪了所有事情,所以我我几乎可以肯定问题出在屏障上。问题是我看不出问题出在哪里:S
public class cyclicBarrier {
private int n;
private int count;
private semaphore mutex;
private semaphore turnstile;
private semaphore turnstile2;
public cyclicBarrier(int n){
this.n = n;
this.count = 0;
this.mutex = new semaphore(1);
this.turnstile = new semaphore(0);
this.turnstile2 = new semaphore(0);
}
public synchronized void down() throws InterruptedException{
this.phase1(); //waits for n threads to arrive
this.phase2(); //waits for n threads to execute
}
private synchronized void phase1() throws InterruptedException {
this.mutex.down();
this.count++;
if(this.count == this.n){
for(int i = 0; i < this.n; i++){
this.turnstile.signal(); //when n threads received then move on to phase 2
}
}
this.mutex.signal();
this.turnstile.down(); //keeps waiting till I get n threads
}
private synchronized void phase2() throws InterruptedException {
this.mutex.down();
this.count--;
if(this.count == 0){
for(int i = 0; i < this.n; i++){
this.turnstile2.signal(); //reset the barrier for reuse
}
}
this.mutex.signal();
this.turnstile2.down(); //keeps waiting till n threads get executed
}
}
public class semaphore {
private int counter;
public semaphore(int number){
if (number > 0) {
this.counter = number;
}
}
public synchronized void signal(){
this.counter++;
notifyAll();
}
public synchronized void down() throws InterruptedException{
while (this.counter <= 0){
wait();
}
this.counter--;
}
}