如何使用 ExecutorService Java 减少到达 Runnable class 的 运行 方法的时间延迟
How to reduce the time delay to reach run method of Runnable class using ExecutorService Java
我试图实现一个实时执行的应用程序,其中按钮单击事件会将任务分配给线程,线程会调用 midi 方法 来播放一些音乐.单击按钮并稍有延迟时,必须立即开始播放音乐。 midi 代码在 Runnable class 的 运行 方法中实现。但是在按钮单击事件本身花费 超过 2 毫秒 之后到达 运行 方法的第一条语句。
我尝试使用 Executor Service,因为它可以收集新创建的线程并减少由线程引起的时间延迟。我是 ExecutorService 应用程序的新手。我观察到的是第一次单击按钮时花费了超过 2 毫秒,但是当它重新启动时延迟减少了。但在某个阶段它也增加到超过 4 毫秒。这种延迟如何每次都保持在不到一毫秒。有没有办法使用 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
正如我在评论中所说,它更像是一种独立于语言的东西。在最小化线程执行间隙方面不可能进行非常简单的优化
可以试试这个。
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
class 的 run
方法中
public void run() {
try {
pool.execute(handlers[(int)Thread.currentThread().getId()]);
} catch (Exception ex) {
pool.shutdown();
}
}
延迟可能是由于 OS 调度造成的,在这种情况下可能没有太多事情要做,或者因为线程池正忙于启动线程或因为您的池已被完全使用。
您可以尝试使用更大的池并预启动所有线程。类似于:
ThreadPoolExecutor tpe = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
tpe.prestartAllCoreThreads();
pool = tpe;
例如池大小为 10。
(第一行相当于Executors.newFixedThreadPool
)
如果您仍然观察到同样的效果,那么您可能需要寻找不同的方法。您的 midi 库可能提供了一种无需使用线程即可异步发送音符的方法,但我不熟悉它,所以我不知道。
另请参阅:https://whosebug.com/search?q=%5Bandroid%5D%20midi%20delay
我试图实现一个实时执行的应用程序,其中按钮单击事件会将任务分配给线程,线程会调用 midi 方法 来播放一些音乐.单击按钮并稍有延迟时,必须立即开始播放音乐。 midi 代码在 Runnable class 的 运行 方法中实现。但是在按钮单击事件本身花费 超过 2 毫秒 之后到达 运行 方法的第一条语句。 我尝试使用 Executor Service,因为它可以收集新创建的线程并减少由线程引起的时间延迟。我是 ExecutorService 应用程序的新手。我观察到的是第一次单击按钮时花费了超过 2 毫秒,但是当它重新启动时延迟减少了。但在某个阶段它也增加到超过 4 毫秒。这种延迟如何每次都保持在不到一毫秒。有没有办法使用 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
正如我在评论中所说,它更像是一种独立于语言的东西。在最小化线程执行间隙方面不可能进行非常简单的优化
可以试试这个。
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
class 的 run
方法中
public void run() {
try {
pool.execute(handlers[(int)Thread.currentThread().getId()]);
} catch (Exception ex) {
pool.shutdown();
}
}
延迟可能是由于 OS 调度造成的,在这种情况下可能没有太多事情要做,或者因为线程池正忙于启动线程或因为您的池已被完全使用。
您可以尝试使用更大的池并预启动所有线程。类似于:
ThreadPoolExecutor tpe = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
tpe.prestartAllCoreThreads();
pool = tpe;
例如池大小为 10。
(第一行相当于Executors.newFixedThreadPool
)
如果您仍然观察到同样的效果,那么您可能需要寻找不同的方法。您的 midi 库可能提供了一种无需使用线程即可异步发送音符的方法,但我不熟悉它,所以我不知道。
另请参阅:https://whosebug.com/search?q=%5Bandroid%5D%20midi%20delay