简体   繁体   English

Java,停止(中断)线程

[英]Java, stopping (interrupting) the thread

Very recently I've asked this question, but wasn unable to fix this. 最近,我问了这个问题,但无法解决。 So I have a thread hunter (2 of them actually), who "goes off to catch wild boars". 因此,我有一个线程猎人(实际上是其中的2个),他“去捉野猪”。 He stores these boars in a container Fridge. 他将这些公猪存储在集装箱冰箱中。 He will continue to do so until his working hours expire. 他将继续这样做,直到他的工作时间到期为止。 However, in case the Fridge is full he has to wait. 但是,如果冰箱已满,他必须等待。 The aim is to wait until a wild boar is removed from the fridge, but if it takes more then 5 seconds of waiting test must be terminated. 目的是要等到野猪从冰箱中取出后才可以,但是如果要花费更多时间,则必须终止5秒钟的等待测试。 So everything works except one thing. 因此,除了一件事情之外,所有东西都有效。 After running test and interrupting these threads, the program still continues to run. 在运行测试并中断了这些线程之后,程序仍然继续运行。 So how do I completely terminate/stop these threads? 那么,如何完全终止/停止这些线程?

TEST CLASS (main) 测试班(主要)

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

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

}

ADDITIONAL CLASSES FOR COMPILING: 编译的其他类:

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

After you interrupt() the thread which is currently waiting, the native wait method will actually reset the interruption flag. 在您interrupt()当前正在等待的线程之后,本机的wait方法实际上将重置中断标志。 So when you evaluate the isInterrupted() here, it is actually reset and will appear as not interrupted. 因此,当您在此处评估isInterrupted() ,它实际上会被重置,并显示为未中断。

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

You will have to re-interrupt the thread after an interruption occurs during the wait ing 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);
}

Currently, the run method in your Hunter thread is discarding interruptions: 当前,您的Hunter线程中的run方法正在丢弃中断:

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

Thus, nothing happens when you later check for interruptions 因此,当您以后检查中断时,什么也不会发生

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

To correct this, you need to set the thread's interrupt status : 要解决此问题,您需要设置线程的中断状态

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

Summary - ignoring the InterruptedException resets the interrupt status. 摘要-忽略InterruptedException重置中断状态。 If you don't or re-throw it or break , then you will need to set the interrupt status manually. 如果不这样做,或者重新抛出或break它,那么您将需要手动设置中断状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM