2016-03-30 6 views
1

私はハッシュを解読するような単純なシミュレーションをしています。その結果、他のすべてのワーカーが結果を見つけたらすぐに停止したいのですか?それは非難されているので、停止以外の方法はありますか?作業中にワーカースレッドを停止するには?

import java.util.Random; 

class Worker extends Thread{ 
int target,start,current,end; 

public Worker(int target, int start, int end) { 
    super(); 
    this.target = target; 
    this.start = start; 
    this.end = end; 
} 

@Override 
public void run() { 
    current=start; 
    while(target!=current){ 
     System.out.println("Not found target at "+current); 
     current++; 
     if(current==end){ 
      break; 
     } 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    if(target==current){ 
     System.out.println(target+" found"); 
    } 
} 

} 
public class RandomBreak { 

public static void main(String[] args) { 
    Random r=new Random(100); 
    int target=r.nextInt(100); 
    System.out.println("trying to search "+target); 

    Worker w1=new Worker(target,1,30); 
    Worker w2=new Worker(target,30,60); 
    Worker w3=new Worker(target,60,90); 
    Worker w4=new Worker(target,90,100); 
    w1.start(); 
    w2.start(); 
    w3.start(); 
    w4.start(); 
} 

} 

答えて

0

スレッドを開始し、リストに追加したループを作り、答えが見つかったときに あなたはその後、他のスレッドを停止し、リストを反復処理することができます。 スレッドプールを使用する場合は、ThreadPoolExecutor.shutdownNow() を使用して、プール内の残りのスレッドをすべて停止させることができます。

+0

メインスレッドは、どのスレッドがそのアイテムを見つけたのか、またはスレッドがその制限を超えたために終了したのかを知ることができます。メインサーバーにこれを通知するにはどうすればいいですか? –

+0

コールバックを設定すると、応答を見つけたスレッドはコールバックを呼び出して自身とその兄弟を終了します –

2

スレッドが答えを見つけたら、他のスレッドでThread.interrupt()を呼び出します。 InterruptedExceptionを捕まえたら、ワーカースレッドを終了します。

あなたの「本当の」コードはのThread.sleepを持っていない場合は()、その後、単にような何か、時折スレッド割り込みフラグをチェック:

if(Thread.interrupted()) { 
    throw new InterruptedException(); 
} 
1

フラグとパスを格納するための共通のデータ構造を使用しますデータ構造の同じインスタンスを各ワーカースレッドに割り当てます。ターゲットを見つけた作業者は、終了する前にフラグを設定します。 whileループのフラグをターゲットと一緒にチェックしてください。コードスニペット:

public WorkStatus { 
    private volatile boolean completed; 

    public boolean isCompleted() { 
     return completed; 
    } 

    public synchronized void markCompleted(boolean completed) { 
     this.completed = completed; 
    } 
} 

public Worker implements Runnable { 

    . 
    . 
    private WorkStatus workStatus; 

    public Worker(int target, int start, int end, WorkStatus workStatus) { 
     . 
     . 
     this.workStatus = workStatus; 
    } 

    @Override 
    public void run() { 
     . 
     while(!workStatus.isCompleted() && target!=current) { 
      . 

     } 

     if(target==current) { 
      workStatus.markCompleted(true); 
      . 
     } 
    } 
} 

すべてのWorkerインスタンスに同じWorkStatusインスタンスが渡されていることを確認してください。

0

スレッドの実行を停止する最も確実な方法は、割り込みを使用して割り込み処理を実装することです。 Thread.interrupt()を使用してスレッドの割り込みステータスを変更し、Thread.currentThread().isInterrupted()を使用して、スレッドが中断しているかどうかを確認できます。

import java.util.Random; 

class Worker extends Thread { 
    int target, start, current, end; 

public Worker(final int target, final int start, final int end) { 
    super(); 
    this.target = target; 
    this.start = start; 
    this.end = end; 
} 

@Override 
public void run() { 
    current = start; 
    while (target != current && !Thread.currentThread().isInterrupted()) { 
     System.out.println("Not found target at " + current); 
     current++; 
     if (current == end) { 
      break; 
     } 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      break; 
     } 
    } 
    if (target == current) { 
     Thread.currentThread().interrupt(); 
     System.out.println(target + " found"); 
    } 
    } 
} 

ワーカースレッドが与えられた番号を検索し、繰り返しスレッドが中断されたかどうかを確認します:
あなたのケースでは、コードは次のようなものを見ることができます。スレッドが中断された場合、別のスレッドがその番号を見つけたことを意味します。スレッドが探している番号を見つけた場合は、Thread.currentThread().interrupt()を呼び出して、その番号が見つかったことをメインメソッドに通知し、他のワーカースレッドを終了させます。
主な方法は次のようになります。

public static void main(final String[] args) { 
    Random r = new Random(100); 
    int target = r.nextInt(100); 
    System.out.println("trying to search " + target); 

    Worker w1 = new Worker(target, 1, 30); 
    Worker w2 = new Worker(target, 30, 60); 
    Worker w3 = new Worker(target, 60, 90); 
    Worker w4 = new Worker(target, 90, 100); 
    w1.start(); 
    w2.start(); 
    w3.start(); 
    w4.start(); 

    while (true) { 
     if (w1.isInterrupted() || w2.isInterrupted() || w3.isInterrupted() || w4.isInterrupted()) { 
      w1.interrupt(); 
      w2.interrupt(); 
      w3.interrupt(); 
      w4.interrupt(); 
      break; 
     } else if (!w1.isAlive() && !w2.isAlive() && !w3.isAlive() && !w4.isAlive()) { 
      System.out.println("Invalid search number."); 
      break; 
     } 
    } 
} 

をmainメソッドでは、スレッドの一つが中断された場合、私たちが繰り返し確認してください。そうであれば、他のスレッドに割り込んで実行を終了します。 if節if (!w1.isAlive() && !w2.isAlive() && !w3.isAlive() && !w4.isAlive())のもう1つの部分は、ユーザーがスレッドが検索しない番号を指定した場合の安全性チェックです。すべてのスレッドが実行を終了し、番号が見つからなかった場合は、プログラムを終了します。

関連する問題