3

I was trying to implement a real-time executing application in which a button click event will assign a task to a Thread , which will call a midi Method to play some music. The music has to be started immediately when button is clicked with a small delay. The midi codes are implemented in the run method of Runnable class. But to reach the 1st statement of run method after the button click event itself is taking more than 2 milli second. I tried to use Executor Service, since it can have collection of newly created threads and it reduce the time delay caused by thread. I am new to ExecutorService application. what i observed was at the first time when the button is clicked its taking more than 2 milli sec but when it is restarted the delay is reduced. but at some stage it is increasing to more than 4 milli sec also.. How this delay can be maintained to less than one milli sec everytime. Is there any way to do it using ExecutorService or any other Service providers... Any helps will be appreciating. Here is my code, how i used ExecutorService, If it is not in the proper way to use it please help me correct it.

 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
4

2 回答 2

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

于 2015-10-16T08:38:06.213 回答
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();
  }
}
于 2015-10-16T05:06:25.133 回答