2011-12-08 8 views
1

スレッドを開始したスレッドからステータスを設定したいスレッドがあります。私はこのコードを持っている:スレッドを制御する変数に割り当てる

public static AnimationThread animThread; 


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

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

} 

私はちょうどスレッドが終了する原因になりますブールフラグを設定されてsetDeadメソッドを呼び出すと、私はNULLポインタを取得しています。 デバッグでは、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)` 
+4

これは明らかに機能するはずなので、残りのコードで何か他のことが起こっているはずです。 NullPointerExceptionを示すスタックトレースと共に、コードをさらに投稿できますか? – ziesemer

+0

このコードで何か問題はありません。問題を実証するためにできるだけ小さなテストをしてから、完全な例を投稿してください。 – erickson

+1

投稿するSSCCE(http://sscce.org/) – nebula

答えて

1

これが原因です。同期がなければ、Javaはあるスレッドから別のスレッドに変更を加える必要はありません。

これを解決するには、Tudorの言葉通りに宣言します。これは、GUIにアクセスする必要がない場合にのみ機能します。

変数を揮発性にしますが、変数が設定される前にGUIが表示される可能性があるため、競合状態になります。

同期ブロック内のanimThread変数の読み取りと書き込みのみです。

guiを作成して表示し、animThreadをすべてEDTに初期化します。

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

    } 
}); 

これは、実行されたアクションが変数が初期化される前に呼び出されないようにします。これは、EDTからanimThread変数にのみアクセスする場合にのみ機能します。

0

名言がありそうgui.launchとして、戻りませんその結果、mainにはanimThreadが初期化されません。次に、animThreadが最初にあなたがそこに来るのでnullであるので、restartを(それの外見によってGUIのボタンを押した結果として)呼び出すとNPEにつながるでしょう。

+0

'gui.lauch'が戻り、最初のインスタンスで変数が設定されています。しかし、ある時点でそのリンクを失う。私のコード内のanimThread変数には他の参照はありません。スレッドクラスでは、私はそれが問題になる可能性がありますか? : 'public AnimationThread(){ \t \t t =新しいスレッド(this、" Animation Thread "); \t \t EventQueue。setAnimationCounter(0); \t \t alive = true; \t \t t.run(); \t} ' – Josh

+0

わかりませんが、' Thread'インスタンスで 'run'を呼び出すと新しいスレッドが生成されません。現在のスレッドで 'Runnable'の' run'を呼び出すだけです。 –

1

は宣言で直接スレッドを初期化してください:あなたは、あなたがそれを割り当てている別のスレッドからの変数を読んでいるので、

public static AnimationThread animThread = new AnimationThread(); 
関連する問題