2012-12-31 117 views
2

我是Java的新手,在尝试实现一个简单的游戏时遇到了一个问题。 当前游戏的前提是,计时器用于添加汽车,并且更频繁地更新汽车的运动。一辆汽车可以通过触摸进行选择,并通过绘制路径进行指导。更新功能将沿着路径移动汽车。两个线程访问同一个LinkedList

现在,游戏的IndexOutOfBoundsException异常崩溃,我几乎可以肯定,这是因为偶然,当汽车重新选择,电流路径擦拭,并允许绘制了一条新路。该路径存储为LinkedList,并在车辆被碰触时清除。

我想象一下,如果通过触摸事件清除路径,而计时器线程正在更新汽车沿路径的移动,这就是错误发生的地方(也有类似的其他问题,可能会出现两个线程访问此一个列表

我的问题,在Java中,处理这个问题的最佳方式是什么?是否应该使用特定类型的列表而不是LinkedList,或者是否存在诸如C++中的Mutex之类的对象,其中在使用它的同时,我可以保护这个列表吗?

+0

需要看到一些代码 – Woot4Moo

回答

8

在Java中,这通常使用synchronization

一个小例子可能是这个样子:

LinkedList list = //Get/build your list 

public void doStuffToList() 
{ 
    synchronized(list) 
    { 
     //Do things to the list 
    } 
} 

public void clearList() 
{ 
    synchronized(list) 
    { 
     list.clear(); 
    } 
} 

此代码不会让,如果有另一个线程当前列表当时在操作执行清除操作。请注意,这会导致阻塞,所以要小心死锁。

另外,如果您的List是,你已经建立了自己的一类,它可能是有道理的,使数据结构线程安全本身:

public class SynchroLinkedList 
{ 
    //Implementation details 

    public synchronized void doThingsToList() 
    { 
     //Implementation 
    } 

    public synchronized void clearList() 
    { 
     //Implementation 
    } 
} 

这两种方法能有效的工作方式相同,但第二个线程的安全性被抽象为数据类型,这很好,因为当你使用这个列表时,你不必担心线程安全。

+0

感谢您的迅速答复,这正是我一直在寻找的。第二种解决方案非常适合我目前的实施,它的作用就像一个魅力! – user1939844

+0

您可能仍需要担心需要原子操作的组合操作(例如迭代)时的线程安全性。 – assylias

0

而是重新创建你自己的线程安全列表实现的,你有几个内置的选项,主要有:

  • 使用synchronized list

    List list = Collections.synchronizedList(new LinkedList()); 
    

    请注意,您需要在同步列表(synchronized(list) { })用于迭代和其他需要原子化的组合操作)

  • 使用一个th请阅读安全集合,例如CopyOnWriteArrayListConcurrenLinkedQueue,如果您不需要访问列表中间的项目,但只需要添加迭代,则这可能是一个不错的选择。

    请注意,根据您的使用情况,CopyOnWriteArrayList可能会有性能损失,特别是如果您经常添加项目(即每隔几微秒)并且该列表可能变大。

相关问题