Java异步是如何工作的?异步方法似乎不是异步运行的
使用Java8 我有一个Logger类,它在需要记录某些内容时调用API。我意识到,如果API配置不当,或者API无法响应,那么我的日志操作将花费大量时间 同步日志记录示例:Java异步是如何工作的?异步方法似乎不是异步运行的,java,performance,asynchronous,Java,Performance,Asynchronous,使用Java8 我有一个Logger类,它在需要记录某些内容时调用API。我意识到,如果API配置不当,或者API无法响应,那么我的日志操作将花费大量时间 同步日志记录示例: public void debug(String message) { MDC.clear(); MDC.put(SOME_KEY, "SOME_VALUE"); super.debug(message); MDC.clear(); } 我能够指出问题出在这里,因为如果我只是评论所有内容,
public void debug(String message) {
MDC.clear();
MDC.put(SOME_KEY, "SOME_VALUE");
super.debug(message);
MDC.clear();
}
我能够指出问题出在这里,因为如果我只是评论所有内容,停止日志记录或做任何事情,所有内容都会以应有的速度运行:
public void debug(String message) {
// MDC.clear();
// MDC.put(SOME_KEY, "SOME_VALUE");
// super.debug(message);
// MDC.clear();
}
因此,我认为这是一个异步调用,因为我不在乎它是否同步记录:
public void debug(String message) {
CompletableFuture.runAsync(() -> {
MDC.clear();
MDC.put(SOME_KEY, "SOME_VALUE");
super.debug(message);
MDC.clear();
});
}
但是对于我的主应用程序来说,这个异步调用和同步调用一样糟糕,性能也很好。我遗漏了什么?你的问题是你没有提供遗嘱执行人。这可能会导致Java为您提供的线程少于您当前等待的调试调用,这意味着您仍然会遇到一些阻塞。在我的4核Intel Core i7-4790和Java 8上的超线程上,我似乎可以同时运行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);
}
}
import java.util.concurrent.CompletableFuture;
导入java.util.concurrent.Executor;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
公开课考试
{
公共静态void main(字符串[]args)引发InterruptedException
{
Executor ex=Executors.newCachedThreadPool();
对于(int i=0;i{
试一试{
时间单位。秒。睡眠(1);
}捕捉(中断异常e){
抛出新的非法状态异常(e);
}
系统输出打印项次(“完成”);
},ex);
}
时间单位。秒。睡眠(2);
}
}
请参见上面的示例,该示例打印“已完成”100次。如果删除ex
参数,它的打印量将大大减少
但是,可能仍然需要修复调试调用缓慢的根本原因,因为如果是长时间运行的任务,这可能会占用您的内存
另见:():
没有显式执行器参数的所有异步方法都是
使用ForkJoinPool.commonPool()执行(除非它没有
支持至少两个并行级别,在这种情况下,新的
创建线程以运行每个任务)。[……]
我会尝试,我也会修复根本原因,但我想首先修复这个问题,因为如果远程日志API不知何故出现几秒钟的故障,我不希望用户受到问题的影响:)它工作正常,非常感谢,我可能已经找了很久了