【发布时间】:2016-05-26 20:12:48
【问题描述】:
我正在尝试在许多线程上编写生命游戏,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() 方法。好吧,它适用于少量单元格,但是当我运行大约 36 个单元格时,它开始变得非常慢,如何修复我的同步以使其更快?
【问题讨论】:
-
请注意,除了个人实验之外,多线程并不是完成此类事情的好方法。正如您所发现的,由于线程开销,性能可能会非常糟糕,而单线程解决方案在整个板上从旧状态计算新状态可能会更好。
-
是的,这是用于个人实验,但只有 36 个线程,而且它们进行的计算非常简单,这就是为什么我如此惊讶,也许有,肯定有更好的同步方法然后我有两个
semaphores -
如果每个单元格有一个线程,那为什么实例方法
Cell.step()需要同步呢?为什么多个线程需要在同一个Cell上争夺对这个方法的访问权? -
我想通过
sendall同步,所以每个单元格都有相同的数据 -
@whd,如果您对
sendall的评论是对我的回应,那么我认为您错过了重点。 Java 同步始终与特定对象的监视器相关。对于带有synchronized关键字的实例方法,该对象就是调用该方法的对象。多个线程都在不同对象上调用相同的synchronized方法,因此彼此根本不同步。
标签: java multithreading concurrency synchronization