如何在不使用Java库中的CyclicBarrier的情况下制作自己的CyclicBarrier

如何在不使用Java库中的CyclicBarrier的情况下制作自己的CyclicBarrier,java,multithreading,java-threads,barrier,cyclicbarrier,Java,Multithreading,Java Threads,Barrier,Cyclicbarrier,我在大学的PacMan game工作,基本上我必须制作自己的CyclicBarrier,因为我不能使用Java的CyclicBarrier库。此屏障将用于在重影到达特定位置(重影目标)时保留重影,并且它们必须等待更多重影,直到我的CyclicBarrier的构造函数中给出最大重影数。重影对象实现可运行(线程) 我是这样建造我的自行车运载工具的: public class Barreira { private int num_threads; private int count;

我在大学的PacMan game工作,基本上我必须制作自己的CyclicBarrier,因为我不能使用Java的CyclicBarrier库。此屏障将用于在重影到达特定位置(重影目标)时保留重影,并且它们必须等待更多重影,直到我的CyclicBarrier的构造函数中给出最大重影数。重影对象实现可运行(线程)

我是这样建造我的自行车运载工具的:

public class Barreira {
    private int num_threads;
    private int count;
    
    public Barreira(int num_threads) {
        this.num_threads=num_threads;
    }
    
    public synchronized void await() {
        while(count < num_threads) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        notifyAll();    
    }
    
    public synchronized void adiciona() {
        count+=1;
    }
    
    public int getNumThreadsNaBarreira() {
        return count;
    }
    
    public synchronized void reset() {
        count=0;
    }

}
public synchronized void arrivePosition(){
...

if((Object)floor[y][x] instanceof GhostGoal && entity instanceof Ghost ) {
            barreira.adiciona();
            barreira.await();
            
        }

}
然而,当一个鬼魂到达该位置时,所有的鬼魂停止移动,而不仅仅是在该位置的鬼魂。。。基本上所有的东西都冻结了,因为我的屏障叫巴雷拉

有人能帮忙吗

多谢各位

我也在考虑这个解决方案(删除wait方法,只使用adiciona方法:

public class Barreira {
    ...
    private List <Ghost> barreiraGhosts = new ArrayList<Ghost>();
    
public synchronized void adiciona(Ghost g) { //teste
    while(contador <num_threads) {
    try {
        contador+=1;
        barreiraGhosts.add(g);
        g.wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }
    notifyAll();
    for(Ghost b: barreiraGhosts)
        b.run();
    reset();
}

}


public synchronized void arrivePosition(){
    ...
    
if((Object)floor[y][x] instanceof GhostGoal && entity instanceof Ghost ) {
            barreira.adiciona(entity);
        }

}
公共类{
...
private List=new ArrayList();
公共同步void adiciona(Ghost g){//teste
而(康塔多Hm…)以下是我在评论中所说的:

public class Test {

    public static void main(String[] args) throws Exception {
        final Thread[] threads = new Thread[5];

        final Barreira barreira = new Barreira(threads.length);

        for (int i = 0; i < threads.length; i++) {
            final Thread thread = new Thread(() -> {
                System.out.println("I'm started");
                barreira.adiciona();
                try {
                    barreira.await();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("I'm finished");
            });
            threads[i] = thread;
        }

        for (final Thread thread : threads) {
            thread.start();
        }

        for (final Thread thread : threads) {
            thread.join();
        }
        System.out.println("All done");
    }

    public static class Barreira {
        private final int num_threads;
        private int count;

        public Barreira(int num_threads) {
            this.num_threads = num_threads;
        }

        public synchronized void await() throws InterruptedException { // it's a common pattern
            // to declare InterruptedException for possible long/time consuming operations
            while (count < num_threads) {
                wait();
            }
        }

        public synchronized void adiciona() {
            count += 1;
            notifyAll();
        }

        public synchronized int getNumThreadsNaBarreira() {
            return count;
        }

        public synchronized void reset() {
            count = 0;
        }
    }
}
公共类测试{
公共静态void main(字符串[]args)引发异常{
最终螺纹[]螺纹=新螺纹[5];
最终巴雷拉=新巴雷拉(螺纹长度);
对于(int i=0;i{
System.out.println(“我开始了”);
巴雷拉·阿迪西奥纳();
试一试{
巴雷拉。等待();
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
System.out.println(“我完成了”);
});
螺纹[i]=螺纹;
}
用于(最终螺纹:螺纹){
thread.start();
}
用于(最终螺纹:螺纹){
thread.join();
}
系统输出打印项次(“全部完成”);
}
公共静态类Barreira{
私有最终int num_线程;
私人整数计数;
公共线程(int num_线程){
this.num_threads=num_threads;
}
public synchronized void await()抛出InterruptedException{//这是一种常见模式
//为可能的长/耗时操作声明InterruptedException
while(计数

工作起来很有魅力。我认为您在使用屏障时遇到了问题,而不是屏障本身…

1.将notifyAll()从wait()移动到adiciona()以通知所有条件都已更改2.为了正式符合JMM,为了防止数据争用,为了保证读者看到getNumThreadSnaberraira()上计数的实际值,您还必须使getter同步,或者将计数定义为volatile。此外,在可能的情况下使用final关键字(对于您的num_线程)。final字段使您的意图更加明确,并且它们具有附加的有用语义(生成冻结动作)就JMM而言,我尝试过,但没有成功,发生了相同的冻结。