我研究一个线程并尝试使用线程制作一个计时器。给主线程写了一段时间
public class A {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please, write the time in ms");
long time = Long.parseLong(reader.readLine());
B thread = new B();
int timer = 0;
try {
thread.start();
Thread.sleep(time);
timer=thread.stop();
}
catch(InterruptedException e) {
System.out.println("Oh....");
}
System.out.println("Result is "+timer);
}
}
并且每个毫秒程序在子线程中写入特定毫秒的名称。
public class B implements Runnable {
private volatile boolean running=true;
private int timer=0;
Thread thread;
public B() {
thread = new Thread(this);
}
public void run() {
while (running) {
System.out.println(timer);
timer++;
try {
Thread.sleep(1);
}
catch(InterruptedException e) {
System.out.println("B");
}
}
}
public int stop() {
running = false;
return timer;
}
public void start() {
thread.start();
}
}
但是当尝试使用参数50得到结果37.我想了解如何在时间中同步它。你能解释我怎么做对吗?
答案 0 :(得分:1)
当时间结束时,只需将变量running
设置为false,它将结束while循环,子线程也将完成。
所以在下面的行之后,尝试将running
变量设置为false
。(提供一些setter方法或者可能在构造函数参数中)
Thread.sleep(time);
答案 1 :(得分:0)
您忘记了Thread.sleep(1)
以外的所有语句也需要时间来执行。最值得注意的是System.out.println(timer)
:这是一个I / O操作,每当发生这样的操作时,它通常会耗费时间(打印到屏幕会使程序等待此阻塞I / O操作完成)。
但我想展示一个更微妙的假设:你还假设当thread.start()
返回时,B.run()
正在执行。情况并非如此,正如以下小程序所示:
import java.util.concurrent.TimeUnit;
public class ThreadTimer implements Runnable {
public static void main(String[] args) {
ThreadTimer tt = new ThreadTimer();
long afterStart = 0L;
new Thread(tt).start();
afterStart = System.nanoTime();
println("After start: " + afterStart);
try {
Thread.sleep(100L);
} catch (Exception e) {
e.printStackTrace();
}
long deltaStart = tt.realStart - afterStart;
println("Delta start: " + deltaStart);
long deltaStartMs = TimeUnit.NANOSECONDS.toMillis(deltaStart);
println("Delta start ms.: " + deltaStartMs);
}
public long realStart;
@Override
public void run() {
realStart = System.nanoTime();
println("Real start : " + realStart);
}
private static void println(String msg) {
System.out.println(msg);
}
}
在我的系统上显示:
After start: 40062314666459 Real start : 40062314706827 Delta start: 40368 Delta start ms.: 0
这意味着失去了一点时间。我确信,如果你衡量执行System.out.println(timer)
需要多长时间,你会看到更多的时间丢失。所有这些小部分最终加起来相当一段时间没有考虑到。
最后一点:System.nanoTime()
和System.currentTimeMillis()
也需要时间来执行(测量时间需要时间)。