重新运行一个帖子

时间:2014-04-07 11:41:19

标签: java android multithreading

在我的安卓游戏中,我正在产生一个单独的线程来播放soundpool类的声音。每次我必须播放声音时,我必须创建一个新线程并执行thread.start()。是否可以创建一次线程并重用?我想这样做,这样我就可以避免产生大量线程的开销。

4 个答案:

答案 0 :(得分:2)

  

是否可以创建一次线程并重复使用?

不可能。

可能的解决方案是使用固定大小的线程池(取决于您的要求),并通过将可运行的任务提交给线程池继续重用它。

确定线程池的完美大小很重要,太少会产生类似问题而太高会产生性能问题。所以你需要做一些基准测试来确定相同的。更好的想法是使其可配置并监控它。

您可能希望在java中查看ExecutorServiceExecutors以了解线程池。

答案 1 :(得分:2)

您可以使用" ThreadPoolExecuter" ..

这是一个很好的例子:

https://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/util/UserTask.java

答案 2 :(得分:1)

您可以使用synchronizedwaitnotify命令创建一个无限的线程,每次触发它时都会播放您的声音。

class InfininteTriggerableThread extends Thread {


    private volatile boolean paused = true;
    private final Object pauseObject = new Object();


    @Override
    public void run(){
        try {
            while(true){
                while (paused) {
                    synchronized(pauseObject) {
                        pauseObject.wait();
                    }
                }
                // do your action here
                paused = true;
            }
        } catch (InterruptedException e) { }
    }



    // trigger method
    public void trigger(){
        paused = false;
        synchronized(pauseObject) {
            pauseObject.notify();
        }
    }

};

答案 3 :(得分:1)

正如我之前所承诺的那样,我测试了使用Looper无限运行的线程,并且可以接受Runnable来逐个执行它们。

// create a custom Thread class
class ThreadWorking extends Thread {

    public volatile Handler handler;

    @Override
    public void run(){
        // between Looper.prepare() and Looper.loop() we need to create a handler
        // which will receive messages and runnables for this thread
        Looper.prepare();
        handler = new Handler();
        Looper.loop();
    }
};

// then create new thread and start it
final ThreadWorking threadWorking = new ThreadWorking();
threadWorking.start();
Log.println(Log.DEBUG, "thread test", "New thread started");

现在新线程正在循环播放,可以通过其Message接收RunnableHandler。它们将存储在内部队列中,并在此特定线程中一个接一个地执行。要进行测试,我会点击按钮发送Runnable

threadWorking.handler.post(new Runnable(){
    @Override
    public void run() {
        try {
             Log.println(Log.DEBUG, "thread test", "Executed: " + System.currentTimeMillis()/1000);
             Thread.sleep(2000);
        } catch (InterruptedException e) { }
    }
});

在我启动应用并快速点击按钮几次后,日志会显示:

04-09 16:21:56.599: D/thread test(19264): New thread started
04-09 16:21:59.569: D/thread test(19264): Executed: 1397046119
04-09 16:22:01.569: D/thread test(19264): Executed: 1397046121
04-09 16:22:03.569: D/thread test(19264): Executed: 1397046123
04-09 16:22:05.569: D/thread test(19264): Executed: 1397046125
04-09 16:22:07.569: D/thread test(19264): Executed: 1397046127
04-09 16:22:09.569: D/thread test(19264): Executed: 1397046129

所以一切都按预期正常工作,不会冻结UI或创建额外的线程。