用Java计算秒数

用Java计算秒数,java,multithreading,count,Java,Multithreading,Count,我正在尝试制作一个简单的小程序,它只计算秒数。 出于某种原因,我的代码从“2”开始,以偶数计数。 仔细查看我的代码后,我不明白为什么它会这样做!有人能帮帮我吗 import java.applet.Applet; import java.awt.Graphics; public class Main extends Applet implements Runnable { int seconds= 0; public void init() { setSize

我正在尝试制作一个简单的小程序,它只计算秒数。 出于某种原因,我的代码从“2”开始,以偶数计数。 仔细查看我的代码后,我不明白为什么它会这样做!有人能帮帮我吗

import java.applet.Applet;
import java.awt.Graphics;

public class Main extends Applet implements Runnable {

    int seconds= 0;
    public void init() {
        setSize(50, 50);
        Thread thread = new Thread(this);
        thread.start();
        Thread timer = new Thread(this);
        timer.start();
    }

    public void run() {

        while (true) {
            try {
                System.out.println(String.valueOf(seconds));
                seconds= seconds +1;
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }

            repaint();
            try {
                Thread.sleep(17);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }   

    public void paint(Graphics g){
    g.drawString(String.valueOf(seconds), 25, 25);
    }
}

首先,启动两个线程,在相同的持续时间内增加相同的变量。这就是为什么它会被计算两次

其次,与其在线程睡眠后递增,不如使用以下方法:

long start = System.currentTimeMillis();
while(true){
    try {
        System.out.println(String.valueOf(seconds));
        seconds= (System.currentTimeMillis()-start)/1000;
        Thread.sleep(500);
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    }
}

我会改变一些事情。首先,你应该扩展。您只需要一个
线程
,应该存储开始时间并计算秒数,您应该在刷新之间清除绘图区域。当我这样改变它时,它在这里起作用-

public class Main extends JApplet implements ActionListener {
  private long startTime = 0;

  final int width = 100;
  final int height = 100;

  public void init() {
    setSize(width, height);
    startTime = System.currentTimeMillis();
    Timer t = new Timer(1000, this);
    t.start();
  }

  @Override
  public void paint(Graphics g) {
    super.paint(g);
    long seconds = (System.currentTimeMillis() - startTime) / 1000l;
    g.clearRect(0, 0, width, height);
    g.drawString(String.valueOf(seconds), 25, 25);
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    long seconds = (System.currentTimeMillis() - startTime) / 1000l;
    System.out.println(seconds);
    repaint();
  }
}

两个线程都在同时更新(足够接近),因此计数器每1000毫秒递增两次shm。。。我该如何着手解决这个问题?谢谢你创建了2个线程。他们几乎同时更新了柜台。所以你会看到偶数。试着只使用一个线程?为什么有线程。睡眠(17)?顺便说一句,如果你想要最好的解决方案,那么应该避免使用Thread.sleep()而使用Timer对象。使用javax.swing.Timer或者使用单个线程,而不是两个线程。1-应该避免从顶级容器(如
JApplet
)进行扩展,而是从
JPanel
之类的容器进行扩展;2-如果要使用基于Swing的API,应该使用
javax.Swing.Timer
;3-你应该给super.paint打电话,因为paint做了很多重要的工作,否则可能会影响apple的输出,所以很多人告诉我使用JApplet。下次我一定会的。不幸的是,这个计时器是我根据一个教程编写的游戏的一部分,因为某种原因,他们使用了applet。我想现在把所有东西重新编程到JApplet可能已经太晚了,所以我正试图找到一种在Applet中制作计时器的方法。除非很容易从Applet转换到JApplet?我不知道,我对这个世界是全新的:p@MadProgrammer编辑。我试图基于OP的现有代码,但我有点懒。这应该解决除第1点以外的所有问题,虽然我大体上同意,但我认为JApplet肯定比Applet好我没有足够的上下文来提出其他建议,但我也会尽可能推荐基于Swing的组件而不是AWT