2016-11-06 4 views
0

私はJavaでプログラムを処理して画像を処理しています。しかし、この画像処理中に、同時に実行されているスイングGUI(およびプログレスバーを含む)は、処理が完了するまでフリーズします。私はこの問題を解決するためにプログラムをマルチスレッド化しようとしましたが、バックグラウンドで処理を実行させましたが、動作しないようです。マルチスレッド時にGUIが互いに干渉するのを防ぐ方法

以下は私が使用しているコードの一部です。

public class GUIThread implements Runnable { 
    public static final int CHOOSER_HUB = 0; 
    public static final int LAUNCH_IMAGE_PREVIEWER = 1; 
    public static final int DISABLE_PREVIEWER_BUTTONS = 2; 
    public static final int MEMORY_USAGE_WINDOW = 3; 
    private int guiNumber; 

    // ========================================================================== 
    // |        START CODE        | 
    // ========================================================================== 

    /** 
    * Runs begins the thread. This method is also for pre-run configuration, 
    * but so far there is none of that. 
    * 
    * @param GUINumber 
    *   The GUI number, indicating which GUI to start. 
    */ 
    public void start(int GUINumber) { 
     DebugMessenger.out("Starting new thread for GUI"); 
     guiNumber = GUINumber; 
     run(); 
    } 

    /** 
    * Starts the thread, and runs a method determined by what guiNumber was set. 
    */ 
    @Override 
    public void run() { 
     DebugMessenger.out("Thread running"); 
     if (guiNumber == GUIThread.CHOOSER_HUB) 
      createChooserHub(); 
     if (guiNumber == GUIThread.LAUNCH_IMAGE_PREVIEWER) 
      createPreviewer(); 
     if (guiNumber == GUIThread.DISABLE_PREVIEWER_BUTTONS) 
      disablePreviewerButtons(); 
     if (guiNumber == GUIThread.MEMORY_USAGE_WINDOW) 
      createMemoryUsageWindow(); 
    } 

    /* More code, including methods called by run() */ 

} 

私のプログラムを起動するには、次のコードを実行するだけです。あなたが見ることができるように

public class Main { 
    /** 
    * Main method. Starts the threads and lets them roll. 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // start threads 
     DebugMessenger.out("Starting Main"); 
     GUIThread guiThread = new GUIThread(); 
     guiThread.start(GUIThread.LAUNCH_IMAGE_PREVIEWER); 
     if(Config.DEBUG_OUTPUT_ENABLED) { 
      memBarThread = new GUIThread(); 
      memBarThread.start(GUIThread.MEMORY_USAGE_WINDOW); 
     } 
     DebugMessenger.out("Main complete"); 
    } 
} 

、私はできるだけシンプルについてマルチスレッドを作ったが、まだ私が実行したときにプログラムや画像プレビューアが処理を開始すると思われ、メモリ使用量ウィンドウがフリーズします。どうすればこれを防ぐことができますか?

答えて

0

ボトルネックになるあなたのコードに欠けている重要なことの1つは、Javaでは、(決して別のスレッドを作成するのではなく、それを実行します)をrunメインスレッド自体)に、むしろあなたがThreadオブジェクトを作成し、以下に示すように、それが別のスレッドでrun()メソッドを呼び出すようにThread()以下のように開始方法を用いたことを開始します:

GUIThreadクラス:

public class GUIThread implements Runnable { 
    public static final int CHOOSER_HUB = 0; 
    public static final int LAUNCH_IMAGE_PREVIEWER = 1; 
    public static final int DISABLE_PREVIEWER_BUTTONS = 2; 
    public static final int MEMORY_USAGE_WINDOW = 3; 
    private int guiNumber; 


    public void setGUINumber(int GUINumber) { 
     this.guiNumber = GUINumber; 
    } 

    @Override 
    public void run() { 
     DebugMessenger.out("Thread running"); 
     if (guiNumber == GUIThread.CHOOSER_HUB) 
      createChooserHub(); 
     if (guiNumber == GUIThread.LAUNCH_IMAGE_PREVIEWER) 
      createPreviewer(); 
     if (guiNumber == GUIThread.DISABLE_PREVIEWER_BUTTONS) 
      disablePreviewerButtons(); 
     if (guiNumber == GUIThread.MEMORY_USAGE_WINDOW) 
      createMemoryUsageWindow(); 
    } 

    /* More code, including methods called by run() */ 

} 

メインクラス:

public class Main { 
    /** 
    * Main method. Starts the threads and lets them roll. 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // start threads 
     DebugMessenger.out("Starting Main"); 

     GUIThread guiThread = new GUIThread(); 
     guiThread. setGUINumber(GUIThread.LAUNCH_IMAGE_PREVIEWER); 

     //Create and Start the Thread now using Thread API 
     Thread threadObj = new Thread(guiThread).start(); 

     if(Config.DEBUG_OUTPUT_ENABLED) { 
      memBarThread = new GUIThread(); 
      memBarThread.start(GUIThread.MEMORY_USAGE_WINDOW); 
     } 
     DebugMessenger.out("Main complete"); 
    } 
} 

、あなたが提供したコードと全くマルチスレッドを使用していないhere

0

を見ることができます。

入力に関係なくGUIThread.start(int)を呼び出すことから始めます。これはメソッドをブロックしていると思われるrun()です。独立した実行を開始するように指示された新しいスレッドはありません。

0

あなたのGUIがフリーズし、私が提案する

は、次の概念を調べますそのアクションはSwing GUIスレッドで実行されているためです。

Runnableを実装する代わりにGUIThreadクラスをThreadに拡張し、スレッドのstartメソッドを呼び出します。

+1

チャームのように働いた!最初の行を 'public class GUIThread extends Thread {'、 'start()'メソッドの名前を 'startThread()'に変更し、 'run()'を 'start()'に置き換えました。 – user119567

+0

@ user119567:お手伝いしてうれしいです。 – fireandfuel

+1

Runnableでスレッドを開始することができます。 Threadを拡張するよりもRunnableを実装するほうが良いでしょう。 –

関連する問題