如何使用ExecutorService Java减少到达Runnable类的run方法的时间延迟

时间:2015-10-16 04:37:37

标签: java threadpool midi executorservice countdownlatch

我正在尝试实现一个实时执行的应用程序,其中按钮点击事件会将任务分配给一个线程,这将调用 midi方法来播放一些音乐。单击按钮时,必须立即启动音乐。 midi代码在Runnable类的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));
   }
 }

输出:

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

2 个答案:

答案 0 :(得分:1)

延迟可能是由于操作系统调度造成的,在这种情况下,可能没什么可做的,或者因为线程池忙于启动线程,或者因为您的池已被完全使用。

您可以尝试使用更大的池并预启动所有线程。类似的东西:

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

答案 1 :(得分:0)

正如我在评论中所说,它更像是一种与语言无关的东西。在最小化线程执行差距方面,不可能进行极简主义优化

可以尝试一下。

private static  TestExecutorSerivice obj=new TestExecutorSerivice(3);;
Handler[] handlers = new Handler[3]; //same as above
for(int i = 0; i<handlers.length; i++)
   handlers[i] = new Handler();
private void handlePlayButtonAction(ActionEvent event) throws InterruptedException {
    Handler.click=System.nanoTime();
    obj.run();
}

并在您的TestExecutorSerivice班级run方法

public void run() { 
  try {
     pool.execute(handlers[(int)Thread.currentThread().getId()]);
  } catch (Exception ex) {
     pool.shutdown();
  }
}