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

2

Andrzej の回答は非常に優れており、彼が提案することを実行する必要があります。始めやすいように簡単な説明を投稿します。

x[1] が c=x[3].x を割り当てようとしているときに、たとえば x[3] が自分自身をロックするとどうなりますか?

データ競合が発生する可能性があります。

データの競合を防ぎたい場合は、同じ変数にアクセスするすべてのスレッドが同期されていることを確認する必要があります。つまり、変数にアクセスする同期ブロックが同じモニターでロックされていることを意味します。

次のようになります。

Colection col;
Object colLock;

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

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

そうすれば、2 つの一連の操作が同時に発生することはなく、データ競合も発生しません。

于 2013-05-08T15:03:27.123 に答える