0

我们有这样的情况

    class Pole extends Thread
{
    JButton pole;
    Plansza p;
    Pole neighbours[] = new Pole[4];
    public Pole(Plansza p)
    {
        this.p = p; 
        pole = new JButton();
        int r,g,b;
        r=p.rndColor();
        g=p.rndColor();
        b=p.rndColor();
        pole.setBackground(new Color(r,g,b));
    }
    public Pole()
    {
        ;
    }

    public void run()
    {
        while(true)
        {
            Thread.yield();
            try
            {
                Thread.sleep((int)p.rndTime());
            }
            catch(InterruptedException e)
            {
                ;
            }
            if(p.rnd.nextDouble()<=1-p.p)
                setNeighboursColor();
            if(p.rnd.nextDouble()<=p.p)
                setRandomColor();
        }
    }

    public void setRandomColor()
    {
        synchronized(this)
        {
            int r,g,b;
            r = p.rndColor();
            g = p.rndColor();
            b = p.rndColor();
            pole.setBackground(new Color(r,g,b));
        }
    }
    public void setNeighboursColor()
    {
        synchronized(this)
        {

            int r,g,b;
            Color c0 = neighbours[0].pole.getBackground();
            Color c1 = neighbours[1].pole.getBackground();
            Color c2 = neighbours[2].pole.getBackground();
            Color c3 = neighbours[3].pole.getBackground();
            r = (int)(c0.getRed() + c1.getRed() + c2.getRed() + c3.getRed())/4;
            g = (int)(c0.getGreen() + c1.getGreen() + c2.getGreen() + c3.getGreen())/4;
            b = (int)(c0.getBlue() + c1.getBlue() + c2.getBlue() + c3.getBlue())/4;
            Color nc = new Color(r,g,b);
            pole.setBackground(nc);
        }
    }
}

我已经编辑了问题并粘贴了我的代码,所以现在每个 Pole(Field) 与其他 4 个 Pole 对象的邻居关系可能更清楚一点,所以我们有很多这样的对象,每个都是不同的线程,它们可以从他们的邻居并将其自身颜色更改为邻居颜色的算术平均值。

4

2 回答 2

3

无意不友善,我认为您对 Java 中的同步如何工作有完全错误的想法。

在 Java 中没有办法“锁定对象”。你的问题并不完全清楚,因为Xs 有一个奇怪的无限嵌套,所以x[1]是模棱两可的。但本质是,如果一个对象试图分配或读取另一个对象的字段,它将成功读/写。它可以等待的唯一方法是它是否选择预先在监视器上同步。(当然,这个等待可以被封装,例如如果c是一个AtomicReference<Color>或类似的 - 它不必明确地完成。)

此外,如果涉及多个线程,那么可见性也会成为一个问题。您必须声明 的数组X以及Color变量,volatile否则无法保证其他线程会看到更新。或者,如果您确实选择走同步路线,并且始终如一地执行此操作,那么可见性也将得到保证(尽管这听起来不符合您的想法)。

我不完全确定您要在这里实现什么,因此无法提供任何设计建议。不过,我确实推荐 Java Concurrency In Practice 一书。并发是困难的,如果你想避免细微的错误,就必须了解它。与任何其他发展领域相比,它需要预先了解这些原则,而不是在问题出现时糊里糊涂。

于 2013-05-08T14:57:04.187 回答
2

Andrzej 的回答非常好,你应该按照他的建议去做。我将发布一个简单的解释来帮助您入门。

如果对象例如 x[3] 锁定自己而 x[1] 将尝试分配 c=x[3].x 会发生什么?

可能会发生数据竞争。

如果你想防止数据竞争,你必须确保所有访问同一个变量的线程都是同步的,这意味着它们访问它的同步块被锁定在同一个监视器上。

它可能看起来像这样:

Colection col;
Object colLock;

void accessCollectionThread1() {
  synchronized(colLock) {
    // do stuff with the collection
  }
}

void accessCollectionThread2() {
  synchronized(colLock) {
    // do other stuff with the collection
  }
}

这样,两个操作序列将永远不会同时发生,也不会发生数据竞争。

于 2013-05-08T15:03:27.123 回答