Tom*_*Tom 4 java performance asynchronous
使用Java 8。
我有一个Logger类,它在需要记录某些内容时会调用API。我意识到,如果API配置不正确,或者API无法解决问题,我的日志操作将花费大量时间。
同步日志记录的示例:
public void debug(String message) {
MDC.clear();
MDC.put(SOME_KEY, "SOME_VALUE");
super.debug(message);
MDC.clear();
}
Run Code Online (Sandbox Code Playgroud)
我能够查明问题出在这里,因为如果我仅评论所有内容并停止记录或执行任何操作,那么一切将以应有的速度运行:
public void debug(String message) {
// MDC.clear();
// MDC.put(SOME_KEY, "SOME_VALUE");
// super.debug(message);
// MDC.clear();
}
Run Code Online (Sandbox Code Playgroud)
所以我想将其异步调用,因为我不在乎是否同步记录它:
public void debug(String message) {
CompletableFuture.runAsync(() -> {
MDC.clear();
MDC.put(SOME_KEY, "SOME_VALUE");
super.debug(message);
MDC.clear();
});
}
Run Code Online (Sandbox Code Playgroud)
但是,对于我的主应用程序而言,异步调用与同步调用一样糟糕,在性能方面也是明智的。我想念什么?
您的问题是您不提供执行者。与当前等待的调试调用相比,这可能导致Java为您提供的线程更少,这意味着您仍然会遇到一些阻塞。在具有4个内核和Java 8上的超线程的Intel Core i7-4790上,我似乎同时运行7个线程(逻辑CPU数-主线程1个)。您可以通过使用缓存的线程池提供无限数量的线程来解决此问题:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Test
{
public static void main(String[] args) throws InterruptedException
{
Executor ex = Executors.newCachedThreadPool();
for(int i=0;i<100;i++)
{
CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
System.out.println("completed");
},ex);
}
TimeUnit.SECONDS.sleep(2);
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅上面的示例,该示例打印“完成” 100次。如果删除该ex参数,它将打印更少的内容。
但是,调试调试缓慢的根本原因可能仍然需要解决,因为如果这是一项长期运行的任务,则可能会占用您的内存。
另请参阅:(https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html):
所有没有显式Executor参数的异步方法都是使用ForkJoinPool.commonPool()执行的(除非它不支持并行度至少为2,在这种情况下,将创建一个新的Thread来运行每个任务)。[...]
| 归档时间: |
|
| 查看次数: |
73 次 |
| 最近记录: |