Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这个演示5次中有4次有效,为什么它有时会给我一个错误?_Java_Applet_Awt_Event Dispatch Thread_Thread Sleep - Fatal编程技术网

Java 这个演示5次中有4次有效,为什么它有时会给我一个错误?

Java 这个演示5次中有4次有效,为什么它有时会给我一个错误?,java,applet,awt,event-dispatch-thread,thread-sleep,Java,Applet,Awt,Event Dispatch Thread,Thread Sleep,我正在练习渲染和绘制图形,我似乎不明白为什么eclipse会在大约1/5的时间内给我一个错误 Exception in thread "Thread-3" java.lang.NullPointerException at game.StartingPoint.run(StartingPoint.java:74) at java.lang.Thread.run(Unknown Source) 我的线程有问题吗?我怎样才能解决这个问题 这是我的源代码 StartingPoint.java

我正在练习渲染和绘制图形,我似乎不明白为什么eclipse会在大约1/5的时间内给我一个错误

Exception in thread "Thread-3" java.lang.NullPointerException
  at game.StartingPoint.run(StartingPoint.java:74)
  at java.lang.Thread.run(Unknown Source)
我的线程有问题吗?我怎样才能解决这个问题

这是我的源代码

StartingPoint.java

package game;

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

public class StartingPoint extends Applet implements Runnable {

    Image i;
    Graphics doubleG;
    Ball b1;
    Ball b2;

    public StartingPoint() {

    }

    @Override
    public void init() {

    }

    @Override
    public void start() {

        setSize(480, 360);

        Thread thread = new Thread(this);
        thread.start();

        b1 = new Ball(40, 40);
        b2 = new Ball(70, 200);

    }

    @Override
    public void stop() {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void update(Graphics g) {

        if (i == null) {
            i = createImage(this.getWidth(), this.getHeight());
            doubleG = i.getGraphics();
        }
        doubleG.setColor(getBackground());
        doubleG.fillRect(0, 0, this.getWidth(), this.getHeight());

        doubleG.setColor(getForeground());
        paint(doubleG);

        g.drawImage(i, 0, 0, this);
    }

    @Override
    public void paint(Graphics g) {
        b1.paint(g);
        b2.paint(g);

    }

    @Override
    public void run() {
        while (true) {

            b1.update(this);
            b2.update(this);

            repaint();
            try {
                Thread.sleep(30);
                } catch (Exception e) {

                System.out.print("Error");

            }
        }

    }
}
package game;

import java.awt.Color;
import java.awt.Graphics;

public class Ball {
    double gravity = 15.0;
    double energyLoss = .65;
    double outsideEnergy = .95;
    double dt = .25;
    double xFriction = .9;
    int x = 40;
    int y = 40;
    double dx = 7.0;
    double dy = 0.0;
    int radius = 20;

    public Ball() {

    }

    public Ball(int x, int y) {

        this.x = x;
        this.y = y;

    }

    public void update(StartingPoint sp) {
        if (x <= 0 | x >= sp.getWidth()) {
            dx = -dx;
        }

        if (y > sp.getHeight() - radius - 1) {
            y = sp.getHeight() - radius - 1;
            dy *= energyLoss;
            dy = -dy;
            dx *= outsideEnergy;
            } else {
            // velocity
            dy = dy + gravity * dt;
            // d=viT + 1/2(a)t^2
            y += dy * dt + .5 * gravity * dt * dt;

        }

        x += dx;
    }

    public void paint(Graphics g) {
        g.setColor(Color.green);
        g.fillOval(x - radius, y - radius, radius * 2, radius * 2);

    }
}
Ball.java

package game;

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

public class StartingPoint extends Applet implements Runnable {

    Image i;
    Graphics doubleG;
    Ball b1;
    Ball b2;

    public StartingPoint() {

    }

    @Override
    public void init() {

    }

    @Override
    public void start() {

        setSize(480, 360);

        Thread thread = new Thread(this);
        thread.start();

        b1 = new Ball(40, 40);
        b2 = new Ball(70, 200);

    }

    @Override
    public void stop() {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void update(Graphics g) {

        if (i == null) {
            i = createImage(this.getWidth(), this.getHeight());
            doubleG = i.getGraphics();
        }
        doubleG.setColor(getBackground());
        doubleG.fillRect(0, 0, this.getWidth(), this.getHeight());

        doubleG.setColor(getForeground());
        paint(doubleG);

        g.drawImage(i, 0, 0, this);
    }

    @Override
    public void paint(Graphics g) {
        b1.paint(g);
        b2.paint(g);

    }

    @Override
    public void run() {
        while (true) {

            b1.update(this);
            b2.update(this);

            repaint();
            try {
                Thread.sleep(30);
                } catch (Exception e) {

                System.out.print("Error");

            }
        }

    }
}
package game;

import java.awt.Color;
import java.awt.Graphics;

public class Ball {
    double gravity = 15.0;
    double energyLoss = .65;
    double outsideEnergy = .95;
    double dt = .25;
    double xFriction = .9;
    int x = 40;
    int y = 40;
    double dx = 7.0;
    double dy = 0.0;
    int radius = 20;

    public Ball() {

    }

    public Ball(int x, int y) {

        this.x = x;
        this.y = y;

    }

    public void update(StartingPoint sp) {
        if (x <= 0 | x >= sp.getWidth()) {
            dx = -dx;
        }

        if (y > sp.getHeight() - radius - 1) {
            y = sp.getHeight() - radius - 1;
            dy *= energyLoss;
            dy = -dy;
            dx *= outsideEnergy;
            } else {
            // velocity
            dy = dy + gravity * dt;
            // d=viT + 1/2(a)t^2
            y += dy * dt + .5 * gravity * dt * dt;

        }

        x += dx;
    }

    public void paint(Graphics g) {
        g.setColor(Color.green);
        g.fillOval(x - radius, y - radius, radius * 2, radius * 2);

    }
}
打包游戏;
导入java.awt.Color;
导入java.awt.Graphics;
公共班级舞会{
双重重力=15.0;
双能量损耗=0.65;
双外能量=.95;
双dt=0.25;
双X摩擦=.9;
int x=40;
int y=40;
双dx=7.0;
双dy=0.0;
int半径=20;
公共舞会{
}
公共球(整数x,整数y){
这个.x=x;
这个。y=y;
}
公共作废更新(StartingPoint sp){
如果(x=sp.getWidth()){
dx=-dx;
}
如果(y>sp.getHeight()-radius-1){
y=sp.getHeight()-半径-1;
dy*=无能量;
dy=-dy;
dx*=外部能量;
}否则{
//速度
dy=dy+重力*dt;
//d=viT+1/2(a)t^2
y+=dy*dt+.5*重力*dt*dt;
}
x+=dx;
}
公共空间涂料(图g){
g、 setColor(Color.green);
g、 圆角(x-半径,y-半径,半径*2,半径*2);
}
}

此错误告诉您b1或b2(或两者)未初始化(即为空)

为什么会出现这种情况需要几分钟的分析,但这是当前的问题

编辑:查看Alex和Chancea的帖子。

这是你的问题:

Thread thread = new Thread(this);
thread.start();

b1 = new Ball(40, 40);
b2 = new Ball(70, 200);
在调用
thread.start()
之前,您需要设置
b1
b2
——调用
start
在新线程中调用
run
方法,并且有可能在初始化这些变量之前调用run方法,从而导致NullPointerException


编辑:

为了解决线程问题,考虑JVM一次只能执行一行代码的概念模型是有用的,只要来自任何一个线程的代码行以正确的顺序执行,不同线程的不同代码行可以以任意顺序交织。对于现代CPU架构,事实并非如此,只是假装

当您在多线程代码中遇到问题时,您的目标是找到一种交叉操作的方法来重现您的问题。例如:

     Thread 1                              Thread2
 1   b1 = null; (implicit in constructor)
 2   b2 = null; (implicit in constructor)
 3   Thread thread = new Thread(this)
 4   thread.start();
 5   b1 = new Ball(40, 40);
 6                                         b1.update(this); (OK because b1 is initialized)
 7                                         b2.update(this); (NPE - b2 is not initialize)
 8   b2 = new Ball(70, 200);
然后,您的目标是重新排列同一线程中的行,以确保不会发生有问题的序列,或者使用诸如
synchronized
块或更高级别的锁之类的语言构造来限制来自不同线程的指令可以交错的方式。

查看

Thread thread = new Thread(this);
thread.start();

b1 = new Ball(40, 40);
b2 = new Ball(70, 200);
线程启动后,您正在初始化变量。有时线程在实际初始化它们之前使用它们,有时首先初始化它们。在调用
start()
之前移动它们:

b1 = new Ball(40, 40);
b2 = new Ball(70, 200);

Thread thread = new Thread(this);
thread.start();

关键词是
Thread
null
。很可能有人认为某些东西是“非线程安全的”。这并不是真正回答你的问题,但我觉得应该提到它。你似乎理解了一些基本的物理原理,并在这里正确地应用了它们,那么为什么不利用向量呢?它将有助于在加速方面对函数进行更多的分类。您可以创建一个恒定的重力向量,并可以连续应用它。只要考虑一下: