2

私はStyledText400x100ウィジェットを使用しており、プログラムがユーザーと対話するコンソールのように機能しています。

これが私がウィジェットを更新する方法です:

private static Shell MainShell = null;

public void createPartControl(Composite parent){
   MainShell = parent.getShell();
}

public static void updateConsole(final String newMessage){
   if(MainShell.isDisposed() || myStyledText.isDisposed() ) return;

   MainShell.getDisplay().syncExec(new Runnable(){
      myStyledText.setText( newMessage + "\n" + myStyledText.getText() );
   });
}

append()に似ていますが、これは最初の行に挿入し、改行「\n」を挿入します。

スレッドを処理するためにCycleBarrierを使用しています。現在、300以上のスレッドを実行しており、CPUを強制終了しないように1サイクルあたり10スレッドのみを許可しています。

// divide 300/10 because there is an inner for() which runs 10 threads / cycle
for(int n = 0; n < 300/10; n++){

   // allow only 10 threads to work
   final CycleBarrier br = new CycleBarrier(10);

   for(int i = 0; i < 10; i++){
      new Thread(new MyClass(cb).start();
   }

   //waiting for Threads to reach the barrier
   br.await();
}

そして今、MyClassクラス:

public MyClass implements Runnable{
   private CycleBarrier cb;

   public MyClass(CycleBarrier cb){
      this.cb = cb;
   }

   @Override
   public void run(){
      for(int i = 0; i < 256; i++){
         for(int j = 0; j < 256; j++){
            //View is the main class (eclipse RCP) and updateing the widget
            View.updateConsole("matrix["+i+"]["+j+"]");

            // Just an integer which counts the number of the loops
            View.TOTAL_LOOPS++;
         }
      }
      cb.await();
   }
}

これは一例です。スレッドは順番にバリアに到達しないため、非同期の方法で(順番ではなく)ビューウィジェットに書き込む必要があります。

eclipse RCP(3.8)を使用しています。

問題

プログラムがDEBUGモードで正しく動作しているのはなぜですか?新しいスレッドを開始するブレークポイントを設定し(for()の内側)、[再開]ボタンをクリックしてスレッドを1つずつ開始します。通常モード(実行またはエクスポート)で開こうとすると、「リーク」(名前の付け方がわかりません)があり、コンソールの行が少なくなります。View.TOTAL_LOOPS合計で次のようになります。

256 * 256 * 10 * 30 = 19660800 // View.TOTAL_LOOPS ++; MyClassで

通常の実行では、動的な結果が得られます:174614904、17025759など。DEBUGモードでは、正確な値に到達しています。

質問:

スレッドは殺されていますか?

4

1 に答える 1

2

SWTとは何の関係もありません。一度に10個のスレッドから1つの共有変数をインクリメントしています。これは競合状態の典型的な例です。は不可分操作ではないため++、次のようなことが発生する可能性があります。

int temp = View.TOTAL_LOOPS; // in thread 1
int temp = View.TOTAL_LOOPS; // in thread 2
int temp2 = temp + 1; // in thread 1
View.TOTAL_LOOPS = temp2; // in thread 1
int temp2 = temp + 1; // in thread 2
View.TOTAL_LOOPS = temp2; // in thread 2

この後、注View.TOTAL_LOOPSは1だけ増加します。もちろん、スレッドを1つずつ開始しても発生しません。

AtomicIntegerスレッドセーフカウンターが必要な場合、またはスレッドを適切に同期する場合は、代わりに使用してください。

于 2013-02-13T20:28:04.150 に答える