我有一个Runnable" NanoClock
"继续在其run()
方法中更新私有volatile double值的类。
此类还有一个getTime()
方法,它返回double值。另一个类(" Master
")正在构建NanoClock
类并创建一个线程,并调用start()
方法。
执行此操作后,它会多次调用getTime()
方法(有延迟),但该值未更新。我做错了什么?
NanoClock.java:
public class NanoClock implements Runnable {
private volatile boolean running;
private volatile double time;
public NanoClock() {
time = System.currentTimeMillis();
}
@Override
public void run() {
running = true;
while(running) {
try {
if(System.currentTimeMillis() > time) {
time = System.currentTimeMillis();
}
//This returns the updated value continuously when commented out
//System.out.println("Time: " + String.format("%.6f", unix_time));
Thread.sleep(2000);
} catch(Exception exc) {
exc.printStackTrace();
System.exit(1);
}
}
}
public double getTime() {
return time;
}
public void end() {
running = false;
}
}
Master.java:
public class Master {
public static void main(String[] args) {
try {
NanoClock nClock = new NanoClock();
Thread clockThread = new Thread(new NanoClock());
clockThread.setPriority(10);
clockThread.start();
//MY_ISSUE: This returns the same value every time
for(int a = 0; a < 10; a++) {
System.out.println("Time: " + nClock.getTime());
}
//MY_ISSUE: This cannot stop the while loop - I tested it with
//the println in the NanoClock class.
nClock.end();
System.out.println("Done!");
catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
答案 0 :(得分:1)
您有两个 NanoClock
个实例:其中一个是匿名new NanoClock()
,因为您的其他帖子中的Runnable
很乐意保留时间在背景中;另一个是nClock
,它在主线程的前台闲置着。
nClock
应该是该另一个帖子中的Runnable
:
Thread clockThread = new Thread(nClock); // not new NanoClock()
这可能不是整个解决方案,但它应该是朝着正确方向迈出的一大步。
答案 1 :(得分:0)
System.currentTimeMillis()
返回一个long,但是你将它存储在double中,这会导致精度损失。当你将成员时间(以及它的getter的返回类型)更改为long时,你应该得到预期的结果。
根据经验:当使用时间单位长时,大多数情况下最合适的数据类型。浮点数不适合存储精确结果。
答案 2 :(得分:0)
如果下面的代码需要2秒钟,那么时间就会改变。
//MY_ISSUE: This returns the same value every time
for(int a = 0; a < 10; a++) {
System.out.println("Time: " + nClock.getTime());
}
然而,具有10次迭代和system.out的for循环甚至不会花费一毫秒,因此它不会改变。
为什么2秒?因为你的可运行代码中有一个Thread.sleep。
Thread.sleep(2000);
这意味着,下一次更新将在2秒内完成。
并且使用System.nanoTime()而不是System.currentTimeMillis()因为你真的想要纳米时间而不是毫秒。
更新:
在我的机器中
public static void main(String args[]) {
long start = System.currentTimeMillis();
for(int a = 0; a < 10; a++) {
System.out.println("Iterating " + a);
}
long end = System.currentTimeMillis();
System.out.println("Start = " + start);
System.out.println("End = " + end);
}
结果,开始时间和结束时间没有区别
Iterating 0
Iterating 1
Iterating 2
Iterating 3
Iterating 4
Iterating 5
Iterating 6
Iterating 7
Iterating 8
Iterating 9
Start = 1499592836298
End = 1499592836298
该代码块的执行速度非常快,甚至不需要一毫秒。根据时间安排,可能需要1毫秒。
将其更改为System.nanoTime()
public static void main(String args[]) {
long start = System.nanoTime();
for(int a = 0; a < 10; a++) {
System.out.println("Iterating " + a);
}
long end = System.nanoTime();
System.out.println("Start = " + start);
System.out.println("End = " + end);
}
结果,开始时间和结束时间存在差异。
Iterating 0
Iterating 1
Iterating 2
Iterating 3
Iterating 4
Iterating 5
Iterating 6
Iterating 7
Iterating 8
Iterating 9
Start = 1012518090518837
End = 1012518091012960
答案 3 :(得分:0)
SELECT * FROM table_name WHERE approved=0
Thread.sleep(2000);
System.out.println("Time: " + nClock.getTime());
中的for
必须为main()