2011-12-20 102 views
1

最近我問了這個問題,但沒有解決這個問題。所以我有一個線索獵人(實際上是其中的兩個),他們「去趕野豬」。他將這些公豬儲存在一個容器冰箱裏。他將繼續這樣做直到他的工作時間到期。但是,如果冰箱已滿,則必須等待。目的是等到野豬從冰箱中取出,但是如果需要等待5秒以上的等待測試才能結束。所以,除了一件事情,一切都有效在運行測試並中斷這些線程之後,程序仍然繼續運行。那麼,我該如何完全終止/停止這些線程呢?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

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

給定的代碼不足以編譯它,例如什麼是Hunter類中的workGen()方法。你能否顯示編譯該程序所需的所有相關代碼? – bbaja42 2011-12-20 19:55:49

+0

@ bbaja42我添加了額外的類 – vedran 2011-12-20 19:58:13

+0

另外,請注意,線程不會在您嘗試停止它們後立即退出,但僅在調用檢查語句(Thread.isInterrupted)時纔會退出。 – bbaja42 2011-12-20 19:58:57

回答

4

在你正在等待的線程interrupt()之後,本地等待方法實際上會重置中斷標誌。所以當你在這裏評估isInterrupted()時,它實際上被重置並且會顯示爲不中斷。

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

您必須將wait荷蘭國際集團

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

目前出現中斷後再次中斷線程,在你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,那麼您將需要手動設置中斷狀態。