让线程睡眠的更好方法

时间:2016-11-12 23:34:05

标签: java multithreading swing netbeans thread-sleep

我在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只做循环。

2 个答案:

答案 0 :(得分:2)

  

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

你觉得你不应该告诉我们你找到的方法,所以我们不花时间制作你已经知道的建议吗?我们不介意读者,我们无法猜测你尝试过的东西。

  

我还没有找到一种方法来包含它们而不会弄乱你的代码。

嗯,无论如何,你的代码应该重新设计。

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

  

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

通常,您不应该使用Thread.sleep(),因为通常代码是由某些用户Action执行的,并且代码在Event Dispatch Thread (EDT)上执行。由于EDT负责绘制GUI,你一直告诉它要睡觉,这显然会影响性能。

但是,在您的情况下,循环逻辑不会在EDT上执行,所以它不应该是一个问题(除了整体设计问题)。

实际上你不应该使用循环。相反,您应该使用Swing Timer来安排动画。

另请参阅Concurrency in Swing教程中的部分,该部分将详细介绍EDT以及为什么应在EDT上更新Swing组件。

答案 1 :(得分:1)

您可以使用Thread.sleep(10)每隔10秒调用while(true)ScheduledExecutorService,而不是在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);

    }    
}