2

私はJavaを初めて使用しますが、単純なゲームを実装しようとすると問題が発生します。現在のゲームの前提は、タイマーを使用して車を追加し、さらに頻繁に車の動きを更新することです。車はタッチで選択でき、パスを描くことで方向を変えることができます。更新機能は、車をパスに沿って移動させます。

現在、ゲームはIndexOutOfBoundsExceptionでクラッシュします。これは、車を再選択すると、現在のパスがワイプされ、新しいパスを描画できるようになることがあるためです。パスはLinkedListとして保存され、車に触れるとクリアされます。

タイマースレッドがパスに沿った車の動きを更新しているときに、タッチイベントによってパスがクリアされた場合、ここでエラーが発生します(2つのスレッドがこの1つのリストにアクセスするときに発生する可能性のある他の同様の問題もあります。

私の質問、Javaで、これに対処する最良の方法は何でしょうか?LinkedListではなく使用する必要のある特定の種類のリストがありますか、それともc ++のMutexなど、作業中にこのリストを保護できるオブジェクトがありますか?

4

2 に答える 2

8

Javaでは、これは通常、同期を使用して実行されます

小さな例は次のようになります。

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
    }
}

これらの2つのアプローチは効果的に同じように機能しますが、2番目のアプローチでは、スレッドセーフがデータ型に抽象化されます。これは、リストを使用するときにスレッドセーフをあちこちで心配する必要がないため便利です。

于 2012-12-31T15:41:26.300 に答える
0

独自のスレッドセーフリストの実装を再作成する代わりに、基本的に次のようないくつかの組み込みオプションがあります。

  • 同期リストを使用する:

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

    synchronized(list) { }アトミックである必要がある反復およびその他の結合された操作については、リスト()で同期する必要があることに注意してください)

  • CopyOnWriteArrayListConcurrenLinkedQueueなどのスレッドセーフなコレクションを使用します。これは、リストの中央にあるアイテムにアクセスする必要はなく、反復を追加するだけでよい場合に適した代替手段になる可能性があります。

    CopyOnWriteArrayListは、ユースケースによってはパフォーマンスが低下する可能性があることに注意してください。特に、定期的に(つまり、数マイクロ秒ごとに)アイテムを追加し、リストが大きくなる可能性がある場合はそうです。

于 2013-01-01T08:03:51.677 に答える