2011-12-20 104 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,那么您将需要手动设置中断状态。