2017-02-22 5 views
0

私はシステム上のユーザ専用のスレッドを持っていますが、それらを個別に停止したいのですが、スレッドのIDを作成時にuserdataとともに保存し、割り込み?または私は何とか私のユーザーオブジェクトにスレッドを追加してちょうどmyuser.mythread.interrupt();のように呼び出すことができますか?オブジェクトへのスレッドIDの定義と割り込み

現在、私はそれらをすべて停止し、必要なスレッドなしで再起動できます。 しかし、それは時間のかかる作業であり、ユーザーが待たなければならない遅れを引き起こします。

アップデート、これは答えでしょうか?

if(delete==true) { 
    if (Thread.currentThread().getId() == deleteId) { 
     Thread.currentThread().interrupt(); 
     delete=false; 
    } 
} 

更新

I)は、(myuser.mythread.interruptを使用する方法を見つけることができました。 または並べ替えの...

私は、ユーザークラスにサブクラスとしてスレッドを追加し、起動して中断し、ユーザのクラスにメソッドを作成し、今私は

online.get(1).hellos(); 
online.get(1).hellosStop(); 

でスレッドを開始し、停止することができます参照を作成して、ユーザーオブジェクト以外のものを追跡する必要はありません。スレッドが離れている場合になりますように、あなただけの、おそらくWeakReferenceで、Threadの参照を格納することができます(私はこのようにそれを行うことができ、参照としてIDを使用して受け入れ答えについて、)

更新

public class MyRunnable implements Runnable { 
    private boolean runThread = true; 
    @Override 
    public void run() { 
     try { 
      while (runThread) { 
       if(delete==true) { 
        if (Thread.currentThread().getId() == deleteId) { 
         Thread.currentThread().interrupt(); 
         delete=false; 
        } 
       } 
       Thread.sleep(5); 
      } 
     } 
     catch (InterruptedException e) { 
      // Interrupted, no need to check flag, just exit 
      return; 
     } 
    } 
} 

答えて

1

それはそれ自身で終了する。

しかし、スレッドはAtomicBoolean(または揮発性のブール値)を毎回チェックしてから、割り込みが発生したかどうかを確認して、スレッドへの参照を必要としないようにすることもできます。

Javaでスレッドを停止することは、停止したいスレッドからの協力がなければ不可能ですが、注意してください。 interruptを使用するかどうかを検査するブール値を使用するかどうかは関係ありません。いずれの場合も、これらのフラグをチェックするスレッドまでです(interruptはフラグを設定します)。終了のような動作をします。

更新 サンプル割り込み可能なスレッドクラス:

public class MyRunnable implements Runnable { 
    private final AtomicBoolean stopFlag; 

    public MyRunnable(AtomicBoolean stopFlag) { 
     this.stopFlag = stopFlag; 
    } 

    @Override 
    public void run() { 
     try { // Try/Catch only needed if you use locks/sleep etc. 
      while (!stopFlag.get()) { 
       // Do some work, but remember to check flag often! 
      } 
     } 
     catch (InterruptedException e) { 
      // Interrupted, no need to check flag, just exit 
      return; 
     } 
    } 
} 
+0

スレッドのメインループを含む 'while(!Thread.interupted()&& isActive)'(isActiveは外側から切り替えられる 'AtomicBoolean'です)を持っています。しかし、多分OPはスレッドのRunnableの内容を変更することはできません。 –

+0

私は真または偽にスレッドを破棄するか、または割り込みキャッチを引き起こすように設定し、そのキャッチ私は再び割り込みを実行するブール値のvarを持っています。これは機能していますが、すべてのスレッドを制御します。スレッドを制御するために変数インジケータを「プログラムで」追加する方法はありますか? 'boolean run_ + thread1 = true;'のように? (run_ + getPassedData){' –

+0

スレッドにフィールドを追加するだけです。スレッドを作成するときは、そのコンストラクタがそのコンストラクタでAtomicBooleanを受け入れるようにしてください。このブール値を変更して、スレッドに停止を通知することができます。 – john16384

0

最善のアプローチは、Threadリファレンスを保存し、それを中断する必要があるコードが利用できるようにすることです。

技術的には(サンドボックス化されていないアプリケーションの場合)、それぞれをテストするすべてのJVMの既存のスレッドのツリーをトラバースすることが可能です。しかし、それは高価で規模を拡大しません。スレッドのIDを格納または渡すことができる場合は、代わりにThread参照を格納または渡すことができます。

独自にWeakHashMap<Long, Thread>を作成し、スレッドIDをスレッドにマッピングすることも技術的に可能です。しかし、同じ議論が適用されます....

if (delete) { 
    if (Thread.currentThread().getId() == deleteId) { 
     Thread.currentThread().interrupt(); 
     delete = false; 
    } 
} 

ありません、それはありません:

あなたは、これが解決策であるかどうか尋ねます。または、スレッドが自分自身を中断している場合にのみ、より正確には「動作する」。それ以外の場合、ターゲットスレッドは中断されません。


あなたのユースケースによっては、これを行うための別の方法はExecutionServiceではなく、裸のスレッドを使用することができます。 submitメソッドは、送信されたタスクを表すFutureオブジェクトを返します。オブジェクトには、cancel(...)メソッドがあります。このメソッドを使用して、タスクをキャンセルするか、実行前に実行中のスレッドを中断することができます。

+0

私は理解すると思います。しかし、 "if(delete)"が現在のスレッドにあり、検索していないので、グローバルdeleteがtrueの場合、グローバルvar deleteIdと同じidを持つスレッドは削除されますか? そして、私はuser.get(id).callStop()でユーザークラスを識別できるように、ユーザークラスのスレッドを持つ方法を見つけました。 –

+0

ええ、私はそれが何であるかを見るためにExecutionServiceを調べます。私はデータ転送の多くをやっているし、実行可能なスレッドは連続したタスクのための最善の選択肢であることを読んだ –

関連する問題