Java,停止(中断)线程

时间:2011-12-20 19:44:33

标签: java multithreading

最近我问过这个问题,但是无法解决这个问题。所以我有一个线程猎人(实际上有两个),他们“去捕野猪”。他将这些公猪存放在一个容器冰箱里。他将继续这样做,直到他的工作时间到期。但是,如果冰箱已满,他必须等待。目的是等到从冰箱中取出野猪,但如果需要超过5秒的等待测试必须终止。所以一切都有效,除了一件事。在运行测试并中断这些线程后,程序仍然继续运行。那么如何完全终止/停止这些线程?

TEST CLASS(主要)

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());
    }
}

猎人课程

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;
            }
        }
    }
}

FRIDGE 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;
    }
}

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:3)

目前,run主题中的Hunter方法正在放弃中断:

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,则需要手动设置中断状态。