2011-12-20 19 views
1

最近、私はこの質問をしましたが、これを修正できませんでした。だから、私はスレッドハンター(実際には2人)がいて、「野生の猪を捕まえるために脱ぐ」。彼は容器の冷蔵庫にこれらの猪を貯蔵する。彼は勤務時間が終了するまでこれを続けます。しかし、冷蔵庫がいっぱいの場合、彼は待たなければなりません。目的は、野生のイノシシが冷蔵庫から取り除かれるまで待つことですが、それ以上の時間がかかる場合は、待機テストを終了する必要があります。 1つのことを除いてすべてが機能します。テストを実行してこれらのスレッドを中断した後も、プログラムは引き続き実行されます。どうすればこれらのスレッドを完全に終了/停止できますか?コンパイルするためJava、スレッドを中断(中断)

class Test { 

    public static void main(String[] args) { 
     test1(); 
    } 

    public static void test1() { 

     Fridge fridge = new Fridge(4); 

     Hunter hunter1 = new Hunter("hunter1", 4, fridge); 
     Hunter hunter2 = new Hunter("hunter2", 7, fridge); 
     Thread hunterThread1 = new Thread(hunter1); 
     Thread hunterThread2 = new Thread(hunter2); 
     hunterThread1.start(); 
     hunterThread2.start(); 

     try { Thread.sleep(1000); } catch (InterruptedException e) {} 
     hunterThread1.interrupt(); 
     hunterThread2.interrupt(); 
     System.out.println(fridge.getSize()); 
     System.out.println(hunter1.getWorkTime()); 
     System.out.println(hunter2.getWorkTime()); 
    } 
} 

HUNTERのクラス

class Hunter extends Worker { 

    private int workTime; 
    private Fridge fridge; 

    public Hunter(String name, int workTime, Fridge fridge) { 
     super(name); 
     this.workTime = workTime; 
     this.fridge = fridge; 
    } 

    public int getWorkTime() { 
     return workTime; 
    } 

    public void run() { 
     while (workTime > 0) { 
      /** Each hunt takes a random amount of time (1-50 ms) **/ 
      try { Thread.sleep(workGen()); } catch (InterruptedException e) {} 
      /** Add new wild boars **/ 
      try { fridge.add(new WildBoar()); } catch (InterruptedException e) {} 
      workTime--; 
      /** If thread is interupted break the loop **/ 
      if(Thread.currentThread().isInterrupted()){ 
       break; 
      } 
     } 
    } 
} 

冷蔵庫CLASS

import java.util.Stack; 

class Fridge extends Storage { 

    private Stack<WildBoar> boars; 

    public Fridge(int cap) { 
     super(cap); 
     boars = new Stack<WildBoar>(); 
    } 

    public int getCap() { 
     return cap; 
    } 

    public int getSize() { 
     return boars.size(); 
    } 

    public boolean hasFreeSpace() { 
     if (boars.size() < cap) 
      return true; 
     else 
      return false; 
    } 

    public synchronized void add(WildBoar boar) throws InterruptedException { 
     /** If there's no free space available wait **/ 
     while (!hasFreeSpace()) { 
      wait(); 
     } 
     /** Once there's free space available add new item **/ 
     boars.add(boar); 

    } 

    public synchronized WildBoar remove() { 
     return boars.pop(); 
    } 

} 

追加のクラス(主)

テストクラス:

abstract class Worker implements Runnable { 

    private String name; 

    public Worker(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

    public int workGen() { 
     return 1 + (int)(Math.random() * (50 - 1)); 
    } 
} 

class WildBoar { 

    public WildBoar() {} 
} 

abstract class Storage { 

    protected int cap; 

    public Storage(int cap) { 
     this.cap = cap; 
    } 

    public int getCap() { 
     return cap; 
    } 
} 
+0

ハンタークラスのworkGen()メソッドなど、コードをコンパイルするのに十分ではありません。プログラムをコンパイルするのに必要なすべてのコードを表示できますか? – bbaja42

+0

@ bbaja42追加のクラスを追加しました – vedran

+0

また、スレッドを停止しようとした直後にスレッドが終了するのではなく、checkステートメント(Thread.isInterrupted)が呼び出されたときにのみ終了することに注意してください。 – bbaja42

答えて

4

interrupt()現在待機しているスレッドの後、ネイティブ待機メソッドは実際に割り込みフラグをリセットします。したがって、ここでisInterrupted()を評価すると、実際にはリセットされ、中断されていないと表示されます。

if(Thread.currentThread().isInterrupted()){ 
    break; 
} 

中断が現在

public synchronized void add(Object boar) { 
    /** If there's no free space available wait **/ 
    while (!hasFreeSpace()) { 
    try{ 
     wait(); 
    }catch(InterruptedException e){ 
     Thread.currentThread().interrupt(); 
     return; //or rethrow 
    } 
    } 
    /** Once there's free space available add new item **/ 
    boars.add(boar); 
} 
3

をINGのwait中に発生した後、あなたが再中断スレッドする必要があります、あなたのHunterスレッド内run方法は、中断を破棄されています

try { fridge.add(new WildBoar()); } 
catch (InterruptedException e) {} 

このように、後で中断をチェックすると何も起こりません。

if(Thread.currentThread().isInterrupted()){ 
    break; 
} 

これを修正するには、スレッドのinterrupt statusを設定する必要があります。

try { fridge.add(new WildBoar()); } 
catch (InterruptedException e) { 
    Thread.currentThread().interrupt(); 
} 

概要 - InterruptedExceptionリセットに割り込みステータスを無視します。あなたがそれを再投げたり、再投げたりしないか、またはbreakの場合は、割り込みステータスを手動で設定する必要があります。