我有一个非常奇怪的情况,我无法理解。我已经定义了一个线程池及其用法
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
....some code.....
logger.info("Event:{}, message:[{}]", Event.MESSAGE.name(), message);
fixedThreadPool.submit(new Runnable() {
@Override
public void run() {
...some code...
}
});
logger.info("Submitted: Event:{}, message:[{}]", Event.MESSAGE.name(), message);
现在这是我的日志消息输出
2017-07-25 20:44:41,020 [New I/O worker #1] XXXXXXXXX.XXXXXXXServiceImpl - Event:MESSAGE, message:[{"delegateTaskId":"_5ejQ7gtTXyfh6qnPrUeJg","sync":true,"accountId":"kmpySmUISimoRrJL6NL73w"}]
2017-07-25 20:45:42,356 [New I/O worker #1] XXXXXXXXX.XXXXXXXServiceImpl - Submitted: Event:MESSAGE, message:[{"delegateTaskId":"_5ejQ7gtTXyfh6qnPrUeJg","sync":true,"accountId":"kmpySmUISimoRrJL6NL73w"}]
查看两条消息的时间戳。虽然我期望提交到线程池的队列应该是立即的,两条消息之间需要差不多一分钟。我试图消除所有可能性,如打印GC日志(没有主要GC暂停),加载模式等。
当我看到这个时,系统没有负载,CPU使用率很低。它运行在亚马逊 EC2 T2LARGE 框中,我可以看到CPU使用率不高。
我阅读了java文档和谷歌,但我找不到任何有用的东西。这非常令人费解。非常感谢任何指针。
------ ----- EDIT
我在日志消息中添加了时间,以确保没有日志记录问题。更新的代码是
logger.info("Event:{}, time:{}, message:[{}]", Event.MESSAGE.name(), new Date(), message);
fixedThreadPool.submit(new Runnable() {
@Override
public void run() {
...some code...
}
});
logger.info("Submitted: Event:{}, time:{}, message:[{}]", Event.MESSAGE.name(), new Date(), message);
这是输出
Event:MESSAGE, time:Wed Jul 26 17:50:18 UTC 2017, message:[{"delegateTaskId":"pN7UzXfzSWajjJY33LbM1A","sync":true,"accountId":"kmpySmUISimoRrJL6NL73w"}]
Submitted: Event:MESSAGE, time:Wed Jul 26 17:51:19 UTC 2017, message:[{"delegateTaskId":"pN7UzXfzSWajjJY33LbM1A","sync":true,"accountId":"kmpySmUISimoRrJL6NL73w"}]
正如您所看到的,在线程池中提交任务所花费的时间几乎是一分钟
答案 0 :(得分:0)
我已经在AWS EC2 t2.large实例上测试了以下代码:
import java.time.Instant;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class RaghvendraSinghTest
{
public static void main(String[] args)
throws Exception
{
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
System.out.printf("[%s] Before fixedThreadPool.submit()%n", Instant.now());
fixedThreadPool.submit(new Runnable() {
@Override
public void run()
{
System.out.printf("[%s] In run()%n", Instant.now());
}
});
System.out.printf("[%s] After fixedThreadPool.submit()%n", Instant.now());
fixedThreadPool.shutdown();
fixedThreadPool.awaitTermination(30, TimeUnit.SECONDS);
System.out.printf("[%s] After fixedThreadPool.shutdown()%n", Instant.now());
}
}
运行代码会产生以下输出:
[2017-07-26T20:11:56.730Z] Before fixedThreadPool.submit()
[2017-07-26T20:11:56.803Z] After fixedThreadPool.submit()
[2017-07-26T20:11:56.803Z] In run()
[2017-07-26T20:11:56.804Z] After fixedThreadPool.shutdown()
这表明整个程序运行时间不到75毫秒。关于你的问题的一点是我的问题是你的线程的名称 - "新的I / O工作者#1" - 这表明我在这里有多个ExecutorService
。
如果您运行我已包含的代码 - 而且只包含我已包含的代码 - 您是否看到与我类似的结果?如果你这样做(我怀疑你会),你应该包含足够的代码,以便我们可以复制你的问题。否则,这似乎特定于您的环境。
答案 1 :(得分:0)
我想出了这个问题。我们的logback.xml中包含以下内容
<appender name="SYSLOG-TLS" class="software.wings.logging.CloudBeesSyslogAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date{ISO8601} %boldGreen(${process_id}) %boldCyan(${version}) %green([%thread]) %highlight(%-5level) %cyan(%logger) - %msg %n</pattern>
</layout>
<host>XXXXXXXX</host>
<port>XXXXXXXX</port>
<programName>XXXXXXXXX</programName>
<key>XXXXXXXXXXX</key>
<threshold>TRACE</threshold>
</appender>
这个配置使得logger.info调用在logdna中发布日志以及我们的系统配置方式,将日志发布到logdna服务器是同步的,有时它需要60秒,我们的任务超时。
现在需要弄清楚为什么这些logdna日志发布调用是同步的。