我试图实现一个实时执行应用程序,其中按钮单击事件将任务分配给 Thread ,该任务将调用MIDI方法播放一些音乐。单击按钮时必须立即开始播放音乐,并有一小段延迟。 midi代码在Runnable类的run方法中实现。但是要在按钮单击事件本身发生后到达 run 方法的第一个语句超过2毫秒。
我尝试使用Executor Service,因为它可以收集新创建的线程,并减少线程引起的时间延迟。我是 ExecutorService 应用程序的新手。我观察到第一次单击按钮时花费了超过 2 毫秒的时间,但是当重新启动时延迟会减少。但在某些阶段,它也会增加到超过 4 毫秒。如何将这种延迟每次保持在不到 1 毫秒。有没有办法使用 ExecutorService 或任何其他服务提供商来做到这一点......任何帮助将不胜感激。
这是我的代码,我是如何使用 ExecutorService 的,如果没有正确使用它,请帮助我纠正它。
private static TestExecutorSerivice obj=new TestExecutorSerivice(3);;
private void handlePlayButtonAction(ActionEvent event) throws InterruptedException {
Handler.click=System.nanoTime();
obj.run();
}
TestExecutorService.java
public class TestExecutorSerivice implements Runnable {
private ExecutorService pool;
public TestExecutorSerivice( int poolSize)
{
pool = Executors.newFixedThreadPool(poolSize);
}
public void run() {
try {
pool.execute(new Handler());
} catch (Exception ex) {
pool.shutdown();
}
}
}
class Handler implements Runnable {
public static long click;
public void run() {
System.out.println("time taken "+(((double)System.nanoTime()-click)/1000000));
}
}
output:
time taken 2.107673
time taken 1.336642
time taken 0.185161
time taken 0.130059
time taken 1.007243
time taken 4.486807
time taken 0.092783
延迟可能是由于操作系统调度造成的,在这种情况下可能没有太多事情可做,或者因为线程池正忙于启动线程,或者因为您的池已完全使用。
您可以尝试使用更大的池并预启动所有线程。就像是:
ThreadPoolExecutor tpe = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
tpe.prestartAllCoreThreads();
pool = tpe;
例如,池大小为 10。
(第一行相当于Executors.newFixedThreadPool
)
如果您仍然观察到相同的效果,那么您可能需要寻找不同的方法。您的 midi 库可能提供了一种异步发送笔记的方法,无需使用线程,但我不熟悉它,所以我不知道。
也可以看看:https://stackoverflow.com/search?q=%5Bandroid%5D%20midi%20delay https://stackoverflow.com/search?q=%5Bandroid%5D%20midi%20delay
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)