如果我在错误的地方或其他地方发布了这些问题,我也是新网站,请原谅我。)
我一直在研究和创建测试程序,试图找出我创建的ScheduledThreadPoolExecutor可能出现的问题。
问题:
运行以下测试应用程序时,计划以3毫秒的固定速率运行的ScheduledThreadPoolExecutor会以大于15毫秒的频繁峰值混乱运行。它应该以每3毫秒的速率执行。
有趣的细节:
问题仅发生在IDE之外,ScheduledThreadPoolExecutor在IDE(如Netbeans或IntelliJ)内按预期运行。
问题:
为什么使用Timer和ScheduledThreadPoolExecutor类会导致非常不一致?执行之间的时间范围从每次执行的预期3毫秒到执行之间的15毫秒的频繁峰值。
配置:
Java 7 Update 5,IntelliJ IDE,Windows 7,从命令提示符运行。
测试应用程序演示此问题,请确保在IDE外部使用以查看问题。该程序将输出的时间大于执行之间的预期时间。应该是大约15毫秒而不是预期的3。
谢谢大家的帮助! :)
package testtime;
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestTime extends JFrame {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestTime().setVisible(true);
}
});
}
JTextArea area = new JTextArea();
JScrollPane pane = new JScrollPane(area);
ScheduledThreadPoolExecutor executor;
public TestTime() {
setSize(300, 300);
setAlwaysOnTop(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
area.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
area.setText("--Press anywhere to start--\n\n" +
"If time exceeds 3 milliseconds it will be printed here...\n\n" +
"------------------------------------\n\n");
executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleAtFixedRate(new Loop(), 0L, 3L, TimeUnit.MILLISECONDS);
}
@Override
public void mouseReleased(MouseEvent e) {
executor.shutdownNow();
}
});
area.setLineWrap(true);
area.setWrapStyleWord(true);
area.setText("--Press anywhere to start--");
add(pane);
}
class Loop extends Thread {
long time = 0L;
@Override
public void run() {
long timeTaken = System.nanoTime() - time;
time = System.nanoTime();
if(timeTaken > 3500000L) {
area.append(timeTaken+"(nanoseconds) -- "+(timeTaken/1000000L)+"(milliseconds)\n");
}
}
}
}
答案 0 :(得分:3)
我认为您的问题来自垃圾收集器,它会定期冻结进程以从内存中删除未使用的对象。
JVM支持几种不同的GC algorithms。在延迟和吞吐量之间存在权衡。
IntelliJ可能使用低暂停GC来支持UI快速响应,而JVM默认使用IDE以外的高吞吐量。
您可以尝试添加-Xincgc
选项(以选择并发标记和扫描)到您的项目吗?
答案 1 :(得分:1)
我认为Windows计时器根本没有这么好的分辨率。如果您使用Google http://www.google.de/search?q=windows+timer+resolution
,您可以找到有关该主题的更多信息答案 2 :(得分:1)
从技术上讲,Timer和ScheduledExecutor接口指定的契约不保证任务将在指定的时间间隔内完全执行。他们只是承诺不会比间隔更快地运行它们。