使用java中的线程计算总运行时间的多线程处理
我有一个java代码,它使用线程来计算从按下开始按钮到不按下停止按钮所经过的时间
我只想使用线程执行此操作
import javax.swing.*;
import java.awt.event.*;
// This will count the elapsed time between running time of two threads.
class ThreadGame {
JButton button;
MyAction my_action;
public static void main(String[] args) {
ThreadGame tg = new ThreadGame();
}
public ThreadGame() {
JFrame frame = new JFrame("Calculate time - Game");
button = new JButton("Start");
button.addActionListener(new MyAction());
frame.add(button);
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class MyAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
String text = (String) e.getActionCommand();
final Timer timer = new Timer();
if (text.equals("Start")) {
button.setText("Stop");
Thread start_time = new Thread() {
public void run() {
timer.startTime();
}
};
start_time.start();
try {
start_time.join();
} catch (Exception e1) {
}
} else {
Thread stop_time = new Thread() {
public void run() {
timer.stopTime();
}
};
Thread get_time = new Thread() {
public void run() {
timer.getElapsedTime();
System.out.println(timer.elapsed);
}
};
stop_time.start();
try {
stop_time.join();
} catch (Exception e2) {
}
get_time.start();
button.setText("Start");
}
}
}
class Timer {
public double startTime = 0.0;
public double stopTime = 0.0;
public boolean running = false;
public double elapsed = 0.0;
public void startTime() {
this.startTime = System.nanoTime();
this.running = true;
}
public void stopTime() {
this.stopTime = System.nanoTime();
this.running = false;
}
// Elasped time in seconds
public double getElapsedTime() {
// double elapsed;
if (running) {
elapsed = ((System.nanoTime() - startTime) / 1000);
} else {
elapsed = ((stopTime - startTime) / 1000);
}
return elapsed;
}
}
}
EDIT:
我理解问题:timer
范围就是问题所在
EDIT 2:
好的,看起来我只能在一个线程中使用suspend
和resume
# 1 楼答案
问题是,start button press启动的对象与stop button press停止的对象不同,因为每次调用
actionPerformed(...)
方法时都会创建Timer
对象Timer
必须是MyAction
类中的字段。您也不需要所有的线程开始/连接,因为Timer
对象非常简单和快速实际上,您可以使用
startTimeMillis
长的字段而不是计时器。比如:# 2 楼答案
单击按钮时,您正在创建一个新的
Timer
。使计时器成为MyAction
的类变量下面的代码应足以获取经过的时间
# 3 楼答案
您的问题是由
timer
的范围引起的这应该是一个私有实例变量,而不是局部方法变量。此外,在线程的run
方法中包装对startTime
和endTime
的调用并没有带来任何好处,因为这些调用的寿命非常短。但这不是这里真正的问题没有理由在自己的线程中运行
Timer
。也就是说,如果不使用专门的实时操作系统,使用线程来解决测量两个事件之间持续时间的问题显然是错误的您可能认为可以创建一个线程,该线程的循环在
Thread.sleep(1)
之后增加一个msec
变量不要这样做这种时间安排也显然是错误的。您的计算机使用抢先多任务模式,这意味着不能保证线程会定期执行。也就是说,没有什么需要Thread.sleep(1)
睡眠一段时间。保证您的线程将至少睡眠1ms。这意味着,如果您自己在软件中管理时钟,则无法确定时钟错误,并且此错误并非无关紧要不要这样做时间应该始终由您的操作系统测量,最好使用基于中断的计时器(这就是System.nanoTime
在大多数平台(如果不是所有平台)上的工作方式)不要使用线程,只需直接从原始线程调用
startTime
和stopTime
方法即可试试这个:
如果您想学习如何使用线程,请尝试编写一个应用程序来解决线程非常适合的问题例如,编写一个小型Swing应用程序,让您从web下载文件。下载文件时,更新UI中的进度条。下载应该在与UI线程分开的工作线程中进行,否则UI将在下载过程中阻塞
另一个示例问题是编写线程光线跟踪器(这里是用C++编写的example tutorial)
如果你想要更简单的东西,写一个摆动时钟。在单独的线程中使用循环以定期更新UI,但不要使用循环来管理时间。同样,不要试图在循环中保留时间,只让操作系统保留时间,并使用循环计划UI何时使用当前操作系统时间更新
# 4 楼答案
只要这样做
-在线程的开始处调用
System.currentTimeMillis()
强>-然后在线程的末尾再次调用
System.currentTimeMillis()
强>-
Subtract
以起始值结束以获取经过的时间/////EDITED/////////strong>
确保试图操纵(即读写)持有
System.currentTimeMillis()
的method
必须与synchronized keyword
同步,以便根据Brian's Law
不会发生竞争条件If you are writing a variable that might next be read by another thread, or reading a variable that might have last been written by another thread, you must use synchronization, and further, both the reader and the writer must synchronize using the same monitor lock.
# 5 楼答案
您从未调用过更新
elapsed
字段的getElapsedTime()