2011-10-03 81 views
1

在阅读了关于Java同步方法的主题之后,我尝试在我的多人游戏中实现它,因为打开了许多线程并尝试访问相同的资源。 我已经使方法同步,但这并没有帮助我,因为如果我有一个数据成员称为ArrayList clientConnection;和可用的方法是:是否可以同步数据成员而不是方法?

int getArrayListSize() { 
    clientConnection.size(); 
} 

void addConnection(ServerConnection i_connection) { 
    clientConnection.add(i_connection); 
} 

void removeConnection(ServerConnection i_connection) { 
    int index = clientConnections.indexOf(i_Connection); 
    clientConnections.remove(index); 
} 

ServerConnection getClientFromArrayListByIndex(int i_Index) { 
    ServerConnection client = this.clientConnections.get(i_Index); 
} 

我试图做一个全球同步的方法,每当一个想使用他需要在操作类型等数据传递的方法之一,他锁定功能。 问题是有2个函数返回void,1个返回int,1个返回ServerConnection,所以我无法创建该全局方法。 我的问题是否有可能在Java中锁定数据成员而不是方法,这样我可以锁定clientConnection数据成员? 谢谢。

+0

在我看来'getArrayListSize'和'getClientFromArrayListByIndex'不属于你的对象的公共接口。如果您能向我们展示实际使用情况,我们可以引导您朝着正确的方向发展。 –

回答

0

您可以使用​​关键字来同步功能。例如:

synchronized ServerConnection getClientFromArrayListByIndex(int i_Index) { 
    ServerConnection client = this.clientConnections.get(i_Index); 
    // ... 
} 
+0

我遇到的问题是,一个线程可以从clientConnection arrayList中删除服务器连接,并且同时另一个线程尝试获取数组列表大小或获取已删除的特定索引中的serverconnection对象,这不正确 – Alon

+0

Then你应该手动指定一个锁对象。您可以基于'clientConnection' ArrayList进行同步,并且一次只有一个线程可以访问该对象。一般的经验法则是在共享的资源上进行同步(因此也是潜在问题的原因)。您还可以考虑使用连续数据结构。 –

+0

此方案可能会导致ArrayIndexOutOfBoundsException,但由于并发问题,它不会使列表处于不确定状态。只要正确记录方法,并且/或者如果索引不再有效就返回null,并且/或者如果索引无效,则抛出自定义异常而不是默认ArrayIndexOutOfBoundsException。 –

0

如果你有一个类,你可以简单地前缀的方法与​​;那么这些方法中只有一个线程。但请想想如果你真的需要这个;它可能会减缓执行速度。如果你有公共领域,你应该让他们私人并创建getter方法。

+0

这是一个gernal笔记;你不应该让所有类的所有方法同步。你应该考虑一下。但我认为,比快速更好的正确。 – MasterCassim

+0

使所有的方法同步会减慢应用程序的权利?如果在同一个数组列表上有不同类型的操作,例如:add,remove,getsize等,如果我有3个线程,并且每个人在同一时间使用不同的方法,那么会怎么办? 。 – Alon

+0

您可以使用synchronizedList或通过arraylist进行同步。 – MasterCassim

3

如果你使所有这些方法同步,那么一次只有一个线程将能够调用任何方法,并且列表将因此以线程安全的方式被访问,只要这些方法能够访问列表(即列表是私人的,没有其他方法使用列表)。

synchronized int getArrayListSize() { ... } 
synchronized void addConnection(ServerConnection i_connection) { ... } 
etc. 
+0

这个问题,我需要更多的方法,可以访问列表,如删除连接或迭代查找连接... – Alon

+0

以及同步这些方法。 –

0

你可以使用Collections.synchronizedList()来包装你List于一体,为所有的方法都是同步的。

这是否比同步类中的方法更好取决于你的方法还有其他什么,以及这些东西是否需要协调。

+0

这听起来像是一个很好的解决方案,你有没有使用的例子? – Alon

+2

除了可能失败的removeConnection()方法外,它会执行两次为每个调用同步的操作,但不是原子单元(并且需要)。另一个线程可能会修改indexOf()和remove()调用之间的列表。 – Todd

+0

我没有发现'removeConnection()'中发生了什么 - 给定代码,这会产生竞争条件,因此不合适。我确实提到这是否合适取决于方法中发生了什么,但是... – uckelman

相关问题