1

我有一个应该对某些事件做出反应的过程。所以当playFromList()被调用时,它会从 soundpool 播放一些声音。然后在一个线程中,我设置了一个标志,并且在 3.5 秒内它不应该播放任何声音。

我得到的是:它会播放声音,然后等待 3.5 秒。如果playFromList()在 3.5 秒内被调用 5 次,它仍然会到达SoundManager.playSound(listNr),并且仍然在 17.5 秒内完成。这不正是我想要的。我想要SoundManager.playSound(listNr)只调用一次的方法。

public class Settings{
    public static boolean flag = false;
}

 public class Main{
 public void playFromList(int listNr,int g){

        if(!Settings.flag){
            SoundManager.playSound(listNr);
            if(g ==0){
                mpVolume((float) 0.3);
                t5sec.run();
            }else{pauseMus();}      
        }           
    }

        private Handler vijfSeconden = new Handler(){
            public void handleMessage(Message msg){
                mpVolume((float)0.8);
            }
        };
        Thread t5sec = new Thread(){
            public void run(){
                if(Settings.flag == false){
                    Settings.flag = true;
                    try {
                        Thread.sleep(3500); 
                    } catch (InterruptedException e) {
                        Settings.flag = false;
                        e.printStackTrace();
                    }
                    vijfSeconden.sendEmptyMessage(0);

                    Settings.flag = false;
                }
            }
        };
 }
4

1 回答 1

0

代码几乎没有问题。可能最奇怪的最重要的事情是 t5sec.run(),在 Java 中,您应该在 Thread 对象上使用 start 方法来启动新线程。如所写,它将在调用线程中执行。第二个问题是绝对缺乏同步,我想解决这个问题的一种方法是在 Settings.flag 中使用 AtomicBoolean 而不是 boolean

另一个问题是每次启动新线程都非常昂贵。从描述中准确地说出你想要做什么有点困难,但如果我的理解是正确的,你应该做这样的事情:

if ( (System.currentTimeInMillis() - lastTimePlayed) < 3500) {
 playSound();
 lastTimePlayed = System.currentTimeInMillis();
}

就是这样,不需要线程。如果您希望您的类是线程安全的,您可能希望使用 AtomicInteger 来保存 lastTimePlayed 值。

于 2012-04-13T22:48:04.643 回答