How to reduce the time delay to reach run method o

2019-07-11 14:20发布

问题:

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

回答1:

The delays could be due to OS scheduling, in which case there is probably not much to do, or because the thread pool is busy starting the threads or because your pool is fully used.

You could try to use a larger pool and prestart all the threads. Something like:

ThreadPoolExecutor tpe = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
tpe.prestartAllCoreThreads();
pool = tpe;

with a pool size of 10 for example.

(The first line is equivalent to Executors.newFixedThreadPool)

If you still observe the same effect, then you will probably need to find a different approach. Your midi library may provide a way to send notes asynchronously without the need to use threads but I'm not familiar with it so I don't know.

See also: https://stackoverflow.com/search?q=%5Bandroid%5D%20midi%20delay



回答2:

As I said in the comments its more of a language independent thing. no to very minimalist optimizations are possible in minimizing thread execution gap

May be give this a try.

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

And in your TestExecutorSerivice class's run method

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