0

这是我第一次使用synchronized关键字,所以我仍然不确定它是如何工作的。我有一个希望被多个线程访问的列表,所以我这样做:

players = Collections.synchronizedList(new ArrayList<Player>(maxPlayers));

现在,我想确保我不会players.add()同时调用players.get(),所以我认为我应该使用同步语句(方法 A 和 B 可以同时调用):

public void A() {
    synchronized(players) {
        players.add(new Player());
    }
}

public void B(String msg) {
    synchronized(players) {
        for(int i = 0;i<players.size();i++) {
            players.get(i).out.println(msg);
        }
    }
}

这是正确的程序吗?如果没有,我应该怎么做?

4

1 回答 1

2

如果您仅通过 synchronizedList 返回的对象访问列表,那么访问应该是线程安全的,但请注意,您可能需要将同步块用于复合操作,例如遍历列表或基于对列表的多次调用做出操作和决策(例如,获取一个值做出决定,然后添加一个值)。

因此,在您的示例中 A() 不需要同步块,但 B() 如果您不希望在迭代期间更改列表或被其他线程读取,则可能。(事实上​​,通过使用计数器进行迭代,需要防止循环终止条件和另一个删除项目的线程之间的竞争条件;但其他迭代方式可能没有这个问题)。

于 2010-08-07T18:20:00.960 回答