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();
}
});