[英]Multithread timer not working correctly
再次,請幫助我! 在下面的代碼中,我想通過按一下按鈕來推動計時器線程並在Label中鍵入它來開始。 每次按該按鈕應啟動一個新線程,並在每個標簽上標記它。 但不幸的是,每個標簽都寫入了相同的計時器。 您能幫我們做對嗎? 如果您能告訴我錯誤,那是什么意思?
public class TimerThreads implements ActionListener{
JFrame jFrame = new JFrame();
JLabel[] labels;
int second = 0;
int minute = 0;
String s = "";
String m = "";
int l = 0;
public TimerThreads(){
JLabel one = new JLabel();
JLabel two = new JLabel();
JLabel three = new JLabel();
JLabel four = new JLabel();
labels = new JLabel[]{one, two, three, four};
jFrame.setLayout(new GridLayout(0, 2, 5, 5));
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JButton start = new JButton("Start");
start.addActionListener(this);
JButton stop = new JButton("Stop");
stop.addActionListener(this);
jFrame.add(start);
jFrame.add(stop);
jFrame.setVisible(true);
jFrame.pack();
}
public static void main(String[] args) {
new TimerThreads();
}
@Override
public void actionPerformed(ActionEvent e) {
String select = e.getActionCommand();
switch(select){
case "Start":
jFrame.add(labels[l]);
jFrame.revalidate();
jFrame.repaint();
TimerThread t = new TimerThread(labels[l]);
t.start();
l++;
break;
case "Stop":
//
break;
}
}
class TimerThread extends Thread{
JLabel jLabel;
public TimerThread(JLabel jLabel) {
this.jLabel = jLabel;
}
@Override
public void run() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
second++;
if(String.valueOf(second).length() == 1){
s = "0";
}
else{
s = "";
}
if(second == 60){
second = 0;
s = "0";
minute++;
}
if(String.valueOf(minute).length() == 1){
m = "0";
}
jLabel.setText(m + String.valueOf(minute) + ":" + s + String.valueOf(second));
}
},0, 1000);
}
}
}
您的錯誤的原因在這里:
public class TimerThreads implements ActionListener {
JFrame jFrame = new JFrame();
JLabel[] labels;
// ***** these fields below
int second = 0;
int minute = 0;
String s = "";
String m = "";
// ***** these fields above
int l = 0;
這四個字段是該類的實例字段,並且由您創建的每個TimerTask實例共享,因此所有字段將顯示相同的准確時間。
解決方案是使這些字段位於嵌套類的本地:
public class TimerThreads implements ActionListener {
JFrame jFrame = new JFrame();
JLabel[] labels;
// int second = 0;
// int minute = 0;
// String s = "";
// String m = "";
int l = 0;
public TimerThreads() {
//.....
}
// ....
class TimerThread extends Thread {
JLabel jLabel;
public TimerThread(JLabel jLabel) {
this.jLabel = jLabel;
}
@Override
public void run() {
java.util.Timer timer = new java.util.Timer();
timer.scheduleAtFixedRate(new TimerTask() {
// ***** add these fields here
int second = 0;
int minute = 0;
String s = "";
String m = "";
話雖如此,由於使用了錯誤的Timer(即java.util.Timer)(應使用Swing Timer或javax.swing.Timer),因此代碼風險很大。 這一點非常重要,因為后一個Timer與Swing事件模型可以很好地配合並防止線程沖突。 請查看Swing計時器教程
其他問題:使用固定大小的數組,如果用戶希望運行4個以上的線程,則可能會出現索引超出范圍的風險。 請改用ArrayList。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.