Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重新运行线程_Java_Android_Multithreading - Fatal编程技术网

Java 重新运行线程

Java 重新运行线程,java,android,multithreading,Java,Android,Multithreading,在我的android游戏中,我正在生成一个单独的线程来播放soundpool类的声音。每次我必须播放声音时,我必须创建一个新线程并执行thread.start()。是否可以一次性创建线程并重用?我希望这样做,以避免产生大量线程的开销 是否可以一次性创建线程并重用 这是不可能的 可能的解决方案是使用固定大小的线程池(取决于您的需求),并通过将可运行任务提交到线程池来继续重用它 确定线程池的完美大小很重要,太小会有类似的问题,太高会有性能问题。因此,您需要进行一些基准测试来确定相同的结果。一个更好的

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

是否可以一次性创建线程并重用

这是不可能的

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

确定线程池的完美大小很重要,太小会有类似的问题,太高会有性能问题。因此,您需要进行一些基准测试来确定相同的结果。一个更好的想法是使其可配置并监视它

您可能想在java中了解线程池

是否可以一次性创建线程并重用

这是不可能的

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

确定线程池的完美大小很重要,太小会有类似的问题,太高会有性能问题。因此,您需要进行一些基准测试来确定相同的结果。一个更好的想法是使其可配置并监视它

您可能想在java中了解线程池。

您可以使用“ThreadPoolExecuter”

这是一个很好的例子:

您可以使用“ThreadPoolExecuter”

这是一个很好的例子:


您可以创建一个无限线程,使用
synchronized
wait
notify
命令,在每次触发时播放声音

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();
        }
    }

};

您可以使用
synchronized
wait
notify
命令创建一个无限线程,在每次触发时播放声音

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();
        }
    }

};

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

// 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");
现在新线程正在循环,可以通过其
处理程序
接收
消息
s和
Runnable
s。它们将存储在内部队列中,并在这个特定线程中一个接一个地执行。要进行测试,请单击按钮发送
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或创建额外线程。

正如我之前承诺的那样,我测试了使用
活套
无限运行的线程,并且可以接受
可运行
一个接一个地执行它们

// 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");
现在新线程正在循环,可以通过其
处理程序
接收
消息
s和
Runnable
s。它们将存储在内部队列中,并在这个特定线程中一个接一个地执行。要进行测试,请单击按钮发送
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或创建额外线程的情况下,一切都能按预期正常工作。

nope,一旦
线程
终止,您需要创建一个新的
线程
,以在
线程
终止后重新运行
可运行
逻辑,您需要创建一个新的
线程
以重新运行
可运行
逻辑如果您想知道处理器在运行(true)和(暂停)循环时是否会做不必要的工作,则不会。线程将暂停,直到同步对象变得可用。当您在调用
等待
后调用
通知
时,对象将被通知已同步,线程将退出
已同步
块。它将退出
while(paused)
并继续执行,正如我在代码中的注释所示。实际上,这里不需要
while(paused)
,您可以使用
if(paused)
代替,但是
while
是传统的且更健壮的方法。当然,只要修改触发器方法,使if paused==true,它将paused设置为false并调用notify,如果paused==false,则将它作为参数接收的某些对象(例如,您的声音)添加到队列中。所以在run()方法中,它应该查看队列并播放每一个声音,直到队列变为空。我找到了另一种运行无限线程的方法,以便它可以逐个接收和执行可运行线程。方法是运行
Looper.prepare()
,然后创建一个处理程序,然后在这个新线程中运行
Looper.loop()
,这样可以将可运行文件发送到这个特定的处理程序,并在它所连接的线程中执行,而不会丢失。明天,如果您想知道处理器在运行(true)和(pause)循环时是否会做不必要的工作,我将返回示例(我也对这个主题感兴趣)——不,不会。线程将暂停,直到同步对象变得可用。当您在调用
等待
后调用
通知
时,对象将被通知已同步,线程将退出
已同步
块。它将退出
while(paused)
并继续执行,正如我在代码中的注释所示。实际上,这里不需要
while(paused)
,您可以使用
if(paused)
代替,但是
while
是传统的且更健壮的方法。当然,只要修改触发器方法,使if paused==true,它将paused设置为false并调用notify,如果paused==false,则将它作为参数接收的某些对象(例如,您的声音)添加到队列中。所以在run()方法中,它应该查看队列并播放每一个声音,直到队列变为空。我找到了另一种运行无限线程的方法,以便它可以逐个接收和执行可运行线程。方法是运行
Looper.prepare()