0

以下のコードはmyIntArrayを同期するために正当ですか?
下部の3つのメソッドがmyIntArrayを順不同に変更するのを防ぎますか?
物事がdelayedMethod1、delayedMethod2、method3の順序で発生し、前のものがmyIntArrayへの変更を完了する前に実行することによってそれらの1つが台無しにならないようにしたい。
下の3つのメソッド宣言には、同期されたキーワードが必要ですか?
下の3つのメソッドには、synchronized(myIntArray)ブロックを含める必要がありますか?
同期されたブロックは、Runnableの内部ではなく、Runnableの周囲に配置する必要がありますか?
コマンドに通知、待機、または参加する必要がありますか?

            public class HelpPlease {

                public int myIntArray[] = new int[100];

                public void chooseSquare() {

                    ...
                    Handler handler=new Handler();
                    final Runnable r = new Runnable()
                    {
                        public void run() 
                        {   
                            synchronized(myIntArray) {
                                delayedMethod1();
                            }
                        }
                    };
                    handler.postDelayed(r, 1000);

                    ...

                    Handler handler2=new Handler();
                    final Runnable r2 = new Runnable()
                    {
                        public void run() 
                        {    
                            synchronized(myIntArray) {
                                delayedMethod2();
                            }
                        }
                    };
                    handler2.postDelayed(r2, 1000);

                    ...

                    synchronized(myIntArray) {
                        method3();
                    }
               }

               public void delayedMethod1() {
                    ...
                    change myIntArray;
                    otherMethodsABC();
               {

               public void delayedMethod2() {
                    ...
                    change myIntArray;
                    otherMethodsDEF();
               }

               public void method3() {
                    ...
                    change myIntArray;
                    otherMethodsGHI();
               }
           }

詳細:ハンドラー/実行可能遅延により、同期していないイベントが発生することがあります

編集:

これは意味がありますか?スレッドを実行するには、スレッドが終了するのを待ちますか?遅延を追加する方法がわからないので、それが要点でした。

                        //Handler handler=new Handler();
                        final Runnable r = new Runnable()
                        {
                            public void run() 
                            {
                                delayedMethod();
                            }
                        };
                        //handler.postDelayed(r, COMPUTER_MOVE_DELAY);

                        ExecutorService es = Executors.newFixedThreadPool(1);

                        final Future f1 = es.submit(r);

                        try
                           {
                               f1.get();
                           }
                           catch (InterruptedException e)
                           {
                               throw new RuntimeException(e);
                           }
                           catch (ExecutionException e)
                           {
                               throw new RuntimeException(e);
                           }
4

1 に答える 1

0

同期されたブロックでこれを実行しようとしないでください。2つのブロックが同時に実行されないことを保証するだけであり、実行される順序は保証されません。遅延メソッドを希望の順序で実行する「親」ランナブルを作成することをお勧めします。または、最初のメソッドを使用して、終了したら、ランナブルを投稿して2番目のメソッドを実行するなど、それらをチェーン化することもできます。

具体的には、遅延が必要で、3つのメソッドを順番に実行する場合は、次のようにコーディングします。

public class HelpPlease {
    public int myIntArray[] = new int[100];
    Handler handler=new Handler();

    public void chooseSquare() {
        ...
        final Runnable r = new Runnable()
        {
            public void run() 
            {
                delayedMethod1();
                delayedMethod2();
                method3();
            }
        };
        handler.postDelayed(r, 1000);
    }

    public void delayedMethod1() {
        ...
        change myIntArray;
        otherMethodsABC();
    }

    public void delayedMethod2() {
        ...
        change myIntArray;
        otherMethodsDEF();
    }

    public void method3() {
        ...
        change myIntArray;
        otherMethodsGHI();
    }
}

同期の必要はまったくありません。単一のを使用して、への複数の呼び出しがランナブルのシリアル化された実行をもたらすことHandlerを保証することが重要です。chooseSquare()

編集:

あなたの最新のコメントに基づいて、これが私が進む方法です。Handlerまず、すべてのアクションスケジューリングコードからアクセスできる単一のオブジェクトを用意します。2つの例を使用するには、次のように実装できます。

public void chooseSquare() {
    . . .
    if (point_scored) {
        makeSquaresGlow(list_of_squares);
        playSound(sound_to_play);
        handler.postDelayed(new Runnable() {
            public void run() {
                makeSquaresNotGlow(list_of_squares);
            }
        }, 1000L);
    }
    if (time_for_attack(purple)) {
        handler.postDelayed(new Runnable() {
            public void run() {
                launchAttack(purple);
            }
        }, 1000L);
    }
}

それがイベントスレッドで呼び出されると仮定するとchooseSquare()、すべて(遅延メソッド呼び出しを含む)も同じスレッドで実行されるため、同期は必要ありません。競合状態が発生する可能性がありますが(launchAttack同時にmakeSquaresNotGlowスケジュールされます)、handler一度に1つずつ実行されます。これらの遅延アクションの順序付けが重要な場合Runnableは、一連のアクションを受け入れ、将来、所定の順序でそれらを実行する「メタ」アクションを定義できます。

于 2012-08-05T20:00:17.577 に答える