0

下面的代码用于同步 myIntArray 是否合法?
它会阻止三个底部方法无序更改 myIntArray 吗?
我希望事情按延迟方法 1、延迟方法 2、方法 3 的顺序发生,而不是在前一个完成对 myIntArray 的更改之前运行而搞砸其中一个。
底部的 3 个方法声明是否需要同步关键字?
底部的 3 个方法是否需要包含 synchronized(myIntArray) 块?
我的同步块应该在 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();
               }
           }

更多细节:处理程序/Runnable 延迟产生有时不同步的事件

编辑:

这有意义吗?运行一个线程等待它完成?不知道如何添加延迟,这就是重点。

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

不要尝试对同步块执行此操作。它只会保证没有两个块会同时运行,而不是它们运行的​​顺序。您最好编写一个“父”可运行文件,以您想要的顺序执行延迟的方法。或者,您可以使用第一种方法,当它完成后,发布一个可运行的方法来运行第二种方法,等等,将它们链接在一起。

更具体地说,如果您想要延迟,然后让三种方法按顺序运行,我会这样编码:

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可供所有操作调度代码访问的对象。要使用您的两个示例,可以按如下方式实现:

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将一次执行一个。如果这些延迟动作的顺序很重要,您可以定义一个“元”动作Runnable,它接受一系列动作并在未来按规定的顺序执行它们。

于 2012-08-05T20:00:17.577 回答