我試圖在很多線程上編寫生命遊戲,1個單元= 1個線程,它需要線程之間的同步,所以沒有線程會開始計算它在新線程沒有完成讀取之前的狀態之前的新狀態。這裏是我的代碼非常慢的同步
public class Cell extends Processor{
private static int count = 0;
private static Semaphore waitForAll = new Semaphore(0);
private static Semaphore waiter = new Semaphore(0);
private IntField isDead;
public Cell(int n)
{
super(n);
count ++;
}
public void initialize()
{
this.algorithmName = Cell.class.getSimpleName();
isDead = new IntField(0);
this.addField(isDead, "state");
}
public synchronized void step()
{
int size = neighbours.size();
IntField[] states = new IntField[size];
int readElementValue = 0;
IntField readElement;
sendAll(new IntField(isDead.getDist()));
Cell.waitForAll.release();
//here wait untill all other threads finish reading
while (Cell.waitForAll.availablePermits() != Cell.count) {
}
//here release semaphore neader lower
Cell.waiter.release();
for (int i = 0; i < neighbours.size(); i++) {
readElement = (IntField) reciveMessage(neighbours.get(i));
states[i] = (IntField) reciveMessage(neighbours.get(i));
}
int alive = 0;
int dead = 0;
for(IntField ii: states)
{
if(ii.getDist() == 1)
alive++;
else
dead++;
}
if(isDead.getDist() == 0)
{
if(alive == 3)
isDead.setValue(1);
else
;
}
else
{
if(alive == 3 || alive == 2)
;
else
isDead.setValue(0);
}
try {
while(Cell.waiter.availablePermits() != Cell.count)
{
;
//if every thread finished reading we can acquire this semaphore
}
Cell.waitForAll.acquire();
while(Cell.waitForAll.availablePermits() != 0)
;
//here we make sure every thread ends step in same moment
Cell.waiter.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
處理器 類擴展thread
和運行方法,如果我打開開關,它會調用step()
方法。以及它對少量細胞的作用很好,但是當我運行ABOU 36細胞時,它開始非常緩慢,如何修復我的同步,使其更快?
就像一個說明,多線程不是一個很好的方式來完成這種事情,除了個人實驗。正如您發現的那樣,由於線程開銷,性能可能會非常糟糕,而單線程解決方案可以更好地從舊板計算新狀態。 – hexafraction
是的,這是爲了個人實驗,但只有36個線程,他們做的非常簡單的計算,這就是爲什麼我很驚訝,也許有,肯定有更好的同步方法,那麼我有兩個'信號燈' – whd
如果每個單元有一個線程,那麼爲什麼實例方法Cell.step()需要同步?爲什麼多個線程需要在同一個'Cell'上爭用這個方法? –