我有一个线程,我想从启动它的线程设置状态。我有这段代码:
public static AnimationThread animThread;
public static void main(String args[]) {
animThread = new AnimationThread();
}
public synchronized static void restart() {
animThread.setDead();
}
当我调用setDead方法时,我得到一个空指针,该方法只是设置一个布尔标志,该标志将导致线程完成。 在调试时,我可以清楚地看到永远不会分配animThread变量。
非常感谢任何帮助。 感谢
public class Manager {
public static Graph graph = new Graph();
public static Gui gui;
public static AnimationThread animThread;
private static boolean forcedNew = false;
public static void main(String args[]) {
gui = new Gui();
gui.launch();
animThread = new AnimationThread();
}
public synchronized static void restart() {
forcedNew = true;
if (EventQueue.getAnimationCounter() != 0) {
EventQueue.insertEvent(EventQueue.getAnimationCounter()+1, new EndOfAlgo());
}
animThread.setDead();
EventQueue.resetEventQueue();
animThread = new AnimationThread();
gui.killGUI();
gui = new Gui();
graph = new Graph();
gui.launch();
forcedNew = false;
}
public static boolean getForcedStatus() {
return forcedNew;
}
}
这是我想从(上面)
控制线程的类堆栈追踪:
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)`
答案 0 :(得分:1)
尝试直接在声明中初始化线程:
public static AnimationThread animThread = new AnimationThread();
答案 1 :(得分:1)
这是因为您正在从另一个线程读取变量然后分配它。如果没有同步,Java不必从另一个线程中可见的一个线程进行更改。
要解决此问题,请按照Tudor所述的方式对其进行初始化。这只有在不需要访问GUI时才有效。
使变量变为volatile,但由于在变量设置之前GUI可见,因此您将遇到竞争条件。
只读取和写入同步块中的animThread变量。
在EDT上创建并显示gui并初始化animThread。
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui = new Gui();
gui.launch();
animThread = new AnimationThread();
}
});
这可以防止在初始化变量之前调用执行的操作方法。这仅在您只从EDT访问animThread变量时才有效。
答案 2 :(得分:0)
Mot可能gui.launch
未返回,因此animThread
中main
将无法初始化restart
。然后调用animThread
(由于在其中按下GUI中的按钮)将导致NPE,因为null
在您第一次到达时仍然是{{1}}。 / p>