Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.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 将线程分配给变量以控制它_Java_Multithreading - Fatal编程技术网

Java 将线程分配给变量以控制它

Java 将线程分配给变量以控制它,java,multithreading,Java,Multithreading,我有一个线程,我想从启动它的线程设置它的状态。我有以下代码: public static AnimationThread animThread; public static void main(String args[]) { animThread = new AnimationThread(); } public synchronized static void restart() { animThread.setDead(); } 当我调用setDead方法时,我得

我有一个线程,我想从启动它的线程设置它的状态。我有以下代码:

public static AnimationThread animThread;


public static void main(String args[]) {
    animThread = new AnimationThread();
}

public synchronized static void restart() {
    animThread.setDead();

}
当我调用setDead方法时,我得到一个空指针,该方法只是设置一个布尔标志,将导致线程完成。 在调试时,我可以清楚地看到animThread变量从未被赋值

非常感谢您的帮助。 谢谢


这是我想要控制线程的类(上面)

堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at animation.main.Manager.restart(Manager.java:27)
at animation.gui.Gui$ListenMenuNew.actionPerformed(Gui.java:112)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)`

不太可能
gui.launch
不会返回,因此
animThread
将不会在
main
中初始化。然后调用
restart
(从外观上看是按下GUI中的按钮的结果)将导致NPE,因为
animThread
在您第一次到达那里时仍然是
null

尝试在声明处直接初始化线程:

public static AnimationThread animThread = new AnimationThread();

这是因为您从不同的线程读取变量,然后分配它。如果没有同步,Java不必在一个线程中对另一个线程进行可见的更改

要解决此问题,请按照Tudor所述的声明对其进行初始化。这仅在不需要访问GUI时才起作用

将变量设置为volatile,但是您将有一个竞争条件,因为在设置变量之前GUI可能是可见的

仅读取和写入同步块中的animThread变量

在EDT上创建并显示gui和初始化animThread

SwingUtilities.invokeLater(new Runnable() {
   public void run() {
     gui = new Gui();
     gui.launch();
     animThread = new AnimationThread();

   }
});

这可以防止在初始化变量之前调用action Executed方法。仅当您仅从EDT访问animThread变量时,这才有效。

根据所显示的内容,这显然应该有效,因此您的代码的其余部分中肯定会发生其他事情。您可以发布更多的代码,以及显示NullPointerException的堆栈跟踪吗?这段代码没有问题。请尽可能缩小测试规模以演示问题,然后发布完整的示例。发布SSCCE()
gui。lauch
将返回,并且变量将在第一个实例中设置。但在某一点上却失去了联系。在我的代码中没有其他引用animThread变量。在thread类中,我有-可能是问题吗
public AnimationThread(){t=new Thread(此为“动画线程”);EventQueue.setAnimationCounter(0);alive=true;t.run();}
不确定,但对
Thread
实例调用
run
不会产生新线程。它只需在当前线程上调用
Runnable
run
SwingUtilities.invokeLater(new Runnable() {
   public void run() {
     gui = new Gui();
     gui.launch();
     animThread = new AnimationThread();

   }
});