使线程睡眠的更好方法



我一直在做一个关于 Java 8 中 2D 图形的教程,当时 NetBeans 给了我一个提示,说做Thread.Sleep会影响性能。但是,尽管我已经能够找到几种更好的方法,但我无法找到一种方法来包含它们而不会弄乱您的代码。

package platformer;
import java.awt.*;
import javax.swing.*;
import java.util.Scanner;
@SuppressWarnings("serial")
public class Platformer extends JPanel {
    int x = 0;//Sets the starting coords. of the ball
    int y = 0;
    private void moveBall() {//How much the ball moves by
        x = x+1;
        y = y+1;
    }
    @Override
      public void paint(Graphics g) {//Essentially al the graphics functions
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.fillOval(x, y, 30, 30);
    }
    public static void main(String[] args) throws InterruptedException {
        Scanner reader = new Scanner(System.in);
        Scanner reader1 = new Scanner(System.in);
        System.out.print("Enter an x-value for the window (whole numbers only): ");
        int setx = reader.nextInt();
        System.out.print("Enter a y-value for the window (whole numbers only): ");
        int sety = reader.nextInt();
        JFrame gameFrame = new JFrame("Sample Frame");//Makes the window variable w/ the name in quotations.
        Platformer game = new Platformer();//'Copies' the graphics functions above into a variable
        gameFrame.add(game);//Adds the above variable into th window
        gameFrame.setSize(setx,sety);//Sets the resolution/size of the window(x,y)
        gameFrame.setVisible(true);//Makse the window visible
        gameFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//Makes the window close when the close button is hit
        while (true){
            game.moveBall();
            game.repaint();
            Thread.sleep(10);
        }
    }    
}

我想知道如何包含一种更好的方法来使线程在循环中休眠,或者使 NetBeans 只执行循环。

虽然我已经能够找到几种更好的方法

好吧,你

不认为你应该告诉我们你找到的方法,这样我们就不会花时间做你已经知道的谎言吗?我们不是读心者,我们无法猜测您尝试过什么。

我一直无法找到一种方法来包含它们而不会弄乱您的代码。

好吧,无论如何,您的代码都应该重新设计。

代码的动画应该是游戏面板的功能,而不是main((方法。因此,您应该在面板中内置startGame()stopGame()等方法,以便您可以调用这些方法。

Netbeans 给了我一个提示,做 thread.sleep 会影响性能。

是的,一般来说,您不应该使用 Thread.sleep((,因为通常代码是作为某些用户操作的结果执行的,并且代码在Event Dispatch Thread (EDT)上执行。由于 EDT 负责绘制 GUI,因此您一直告诉它进入睡眠状态,因此这显然会影响性能。

但是,在您的情况下,循环逻辑不会在 EDT 上执行,因此它应该不是问题(整体设计问题除外(。

实际上,您不应该使用循环。相反,您应该使用摆动计时器来安排动画。

另请查看教程中关于Concurrency in Swing的部分,该部分将解释有关EDT的更多信息以及为什么应该在EDT上更新 Swing 组件。

而不是在while(true)中使用Thread.sleep(10),您可以使用ScheduledExecutorService每 10 秒调用一次 moveBall()paint()

,如下所示:
public class Platformer extends JPanel implements Runnable {
    int x = 0;//Sets the starting coords. of the ball
    int y = 0;
    public void add() {
            JFrame gameFrame = new JFrame("Sample Frame");//Makes the window variable w/ the name in quotations.
        Platformer game = new Platformer();//'Copies' the graphics functions above into a variable
        gameFrame.add(game);//Adds the above variable into th window
        gameFrame.setSize(setx,sety);//Sets the resolution/size of the window(x,y)
        gameFrame.setVisible(true);//Makse the window visible
        gameFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//Makes the window close when the close button is hit
    }
      private void moveBall() {//How much the ball moves by
        x = x+1;
        y = y+1;
     }

     @Override
      public void paint(Graphics g) {//Essentially al the graphics functions
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.fillOval(x, y, 30, 30);
    }

     @Override
     public void run() {
        //this code will be executed for every 10 seconds
        moveBall();
        paint();
     }

    public static void main(String[] args) throws InterruptedException {
        Scanner reader = new Scanner(System.in);
        Scanner reader1 = new Scanner(System.in);
        System.out.print("Enter an x-value for the window (whole numbers only): ");
        int setx = reader.nextInt();
        System.out.print("Enter a y-value for the window (whole numbers only): ");
        int sety = reader.nextInt();
        JFrame gameFrame = new JFrame("Sample Frame");//Makes the window variable w/ the name in quotations.
        Platformer game = new Platformer();//'Copies' the graphics functions above into a variable
        gameFrame.add(game);//Adds the above variable into th window
        gameFrame.setSize(setx,sety);//Sets the resolution/size of the window(x,y)
        gameFrame.setVisible(true);//Makse the window visible
        gameFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//Makes the window close when the close button is hit
        //schedule it to run for every 10 seconds
        //this calls the run() method above
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(game, 0, 10, TimeUnit.SECONDS);
    }    
}

相关内容

  • 没有找到相关文章

最新更新