首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >包含方法调用的同步块,这会起作用吗?

包含方法调用的同步块,这会起作用吗?
EN

Stack Overflow用户
提问于 2012-08-06 03:55:56
回答 1查看 1.2K关注 0票数 0

下面的代码是否可用于同步myIntArray?

它能防止三个底层方法无序地更改myIntArray吗?

我希望事情按delayedMethod1,delayedMethod2,method3的顺序发生,而不是在前一个完成对myIntArray的更改之前就把其中一个搞砸了。

下面3个方法声明是否需要synchronized关键字?

下面3个方法是否需要包含同步(MyIntArray)块?

我的同步代码块应该在Runnable周围而不是在它里面吗?

我需要notify、wait或join命令吗?

代码语言:javascript
复制
            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/Runnable delays producing events that are out of sync sometimes

编辑:

这有意义吗?来运行一个线程并等待它完成?我不确定如何增加延迟,这就是问题的关键。

代码语言:javascript
复制
                        //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);
                           }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-06 04:00:18

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

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

代码语言:javascript
复制
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对象。为了使用您的两个示例,可以按如下方式实现它们:

代码语言:javascript
复制
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(),则所有内容(包括延迟的方法调用)也将在同一线程上运行,因此不需要同步。可能存在竞争条件(launchAttackmakeSquaresNotGlow将同时调度),但handler将一次执行一个。如果这些延迟操作的顺序至关重要,您可以定义一个“元”操作Runnable,它接受一系列操作并在将来按规定的顺序执行它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11819605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档