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
  • I guess what you are trying to achieve is more of a hardware ,machine ,JVM or OS dependent. In such scenarios code optimization is a bit more tricky. – Minato Oct 16 '15 at 04:47
  • For example In the above case or in general you can pre create/ initialize all the threads and execute them when needed. – Minato Oct 16 '15 at 04:50
  • 2
    You might be able to cut the time down a bit by not handling thread instantiation when calling run and instead maintaining a pool of the threads passively. It's the only part of the code I can see that would be causing a slow down in execution. – James S Oct 16 '15 at 04:50
  • @Shana Are you always using the same instance of TestExecutorService? – assylias Oct 16 '15 at 07:48
  • @assylias Yes i am using the same instance.. – Shana Kalyan Oct 16 '15 at 07:50
  • Is your application executed on a real-time OS ? Do you use a real-time JVM ? If one (or both) answer is _no_ then there's no way to **guarantee** that delay; only tricks to reduce the probability this delay will be exceeded. – Spotted Oct 16 '15 at 09:04

2 Answers2

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

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
  • 1
    Thank you @assylias.. it has made a huge difference. now it has become 0.7 to .2 millisecond. Initially by mistake i forgot to comment the line Executors.newFixedThreadPool , feel sorry for that mistake i did. Any way thank you very much for you kind and help.. it was very helpful for me.. Thank you Thank you very much.. – Shana Kalyan Oct 17 '15 at 06:04
0

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();
  }
}
Minato
  • 4,383
  • 1
  • 22
  • 28