将线程分配给变量来控制它

时间:2011-12-08 14:25:58

标签: java multithreading

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

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)`

3 个答案:

答案 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未返回,因此animThreadmain将无法初始化restart。然后调用animThread(由于在其中按下GUI中的按钮)将导致NPE,因为null在您第一次到达时仍然是{{1}}。 / p>