gpt4 book ai didi

java - 定时器任务没有启动

转载 作者:行者123 更新时间:2023-12-01 23:21:09 26 4
gpt4 key购买 nike

我在A类的构造函数中编写代码来创建MetricData对象并在其中启动计时器。定时器每隔 2 秒调用方法向属性数组填充随机数,数据填充在定时器启动时立即开始。我在 propertyValue = propertyMetricData.getFirstDataPoint(); 上得到了一个 NPE,我假设调用该方法时数组中没有数据,但是当我处于 Debug模式下逐个命令执行命令时,有时会出现这种情况有效(大约 4/10 倍有效)。所以我想问题可能与时间有关?就像调用 getFirstDataPoint() 时,计时器中的 fillData() 尚未调用?我找不到问题出在哪里,所以请帮助我,。

================================== A类的构造函数 =========== =====================

public A(){

propertyMetricData = new MetricData();
propertyValue = propertyMetricData.getFirstDataPoint();
{

================================== MetricData 类 ============= =====================

public class MetricData {

private Timer timer = new Timer();;
private DecimalFormat df = new DecimalFormat("###.##");
private Random rand = new Random();
private ArrayList<Double> dataPoints = new ArrayList<Double>();

public MetricData(){

startTimer();
}

public ArrayList<Double> getDataPoints(){
return dataPoints;
}

public Double getFirstDataPoint(){
return dataPoints.get(0);
}

private void startTimer(){

timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
fillData();
}
}, 0, 2*1000);
}

private void fillData(){

dataPoints.clear();

for(int i=0; i<100; i++){
dataPoints.add(genRanNum(1,10));
}
}

private Double genRanNum(int min, int max){

double number = min + (rand.nextDouble()*(max - min));

return Double.valueOf(df.format(number));
}

public void testTimer(){
System.out.println(getFirstDataPoint());
}
}

最佳答案

首先,出于安全原因,请同步对 dataPoints 的所有访问,因为您将从不同的线程访问它。一些奇怪的同步问题可以由此解决。

public class MetricData {
...

public Double getFirstDataPoint(){
synchronized(dataPoints) {
return dataPoints.get(0);
}
}

private void fillData(){
synchronized (dataPoints) {
dataPoints.clear();

for(int i=0; i<100; i++){
dataPoints.add(genRanNum(1,10));
}
}
}
}

其次,您正在异步执行 Timer,因此 A() 构造函数中的第二行不会等待任何内容运行,因此很可能不会得到任何结果。

这是一个逻辑问题。我不知道这段代码的意思,但也许如果将 propertyValue = propertyMetricData.getFirstDataPoint(); 行从构造函数移动到 getter 方法会给你更好的结果,因为它'仅在需要时调用,而不是在对象创建时调用(并且会给计时器一些时间来工作):

public A() {
propertyMetricData = new MetricData();
{

public Double getPropertyValue() {
return propertyMetricData.getFirstDataPoint();
}

但我最好的建议是深呼吸并检查你的逻辑。

关于java - 定时器任务没有启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20616459/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com