我有一個應執行器服務,應該每分鐘將一些事情寫入磁盤。ScheduledExecutorService在1分鐘的計劃中滑倒10分鐘(systemd - journald fault)
它計劃是這樣的:
scheduledCacheDump = new ScheduledThreadPoolExecutor(1);
scheduledCacheDump.scheduleAtFixedRate(this::saveCachedRecords,
60,
60,
TimeUnit.SECONDS
);
任務會使用由主線程填充共享列表,所以它是名單上的同步:
private void saveCachedRecords() {
LOG.info(String.format("Scheduled record dump to disk. We have %d records to save.", recordCache.size()));
synchronized (recordCache) {
Iterator<Record> iterator = recordCache.iterator();
while (iterator.hasNext()) {
// save record to disk
iterator.remove();
}
}
}
我的名單宣佈因此:
private final List<Record> recordCache = new ArrayList<>();
主線程按批次接收數據,所以每隔一秒左右,它會收到30個r它將它緩存在列表中。剩下的時間在插座上等待。
什麼我不明白的是,從日誌中,我的計劃任務往往與方式更觸發1分鐘之間:看
sept. 16 09:30:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:31:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:32:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:33:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:34:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:35:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:42:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:43:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:44:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:45:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:46:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:55:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:56:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:57:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:58:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 09:59:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 10:04:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 10:05:43 Scheduled record dump to disk. We have 27 records to save. sept. 16 10:06:43 Scheduled record dump to disk. We have 27 records to save.
在此:
- sept。 16 09:59:43計劃記錄轉儲到磁盤。我們有27條記錄要保存。
- sept。 16 10:04:43計劃記錄轉儲到磁盤。我們有27條記錄要保存。
=>5分鐘
甚至:
- 九月16 09:46:43計劃記錄轉儲到磁盤。我們有27條記錄要保存。
- sept。 16 09:55:43計劃記錄轉儲到磁盤。我們有27條記錄要保存。
=>9分鐘
我的日誌是在synchronized()
範圍,所以我不知道如果任務實際調度在時間和鎖等待10分鐘,或者如果它僅僅是一個真正的調度問題。我將把它移出它,但通常我無法理解一個線程可以在每秒鐘釋放的鎖上停留10分鐘。
我該如何調查?
有關信息:它運行的機器是KVM機器,這可能是一個因素嗎?
您是否檢查過GC活動? –
我沒有。是否有一個CLI工具來做到這一點(我不承認Java管理員的專家)我承認 – Gui13
與您的問題無關,但考慮使用ConcurrentLinkedQueue而不是ArrayList,它是線程安全的,並且Queue似乎是比您需要的列表更合適 –