线程不可中断

问题描述 投票:0回答:1

我正在尝试着名的餐饮哲学家,并且已经完成,但是我很难中断线程。

因此,您知道在这个问题中,我们有5个线程(哲学家),并且用户设置了实验结束的实验时间。

值得注意的是,我在StackOverflow上看到了多个答案。

第一个来自@Konrad Reiche How do you kill a Thread in Java? /Stackoverflow link

在那个特定的帖子中,人们说使用volatile布尔值作为标志可能会奏效,但恐怕练习纸中说我不能使用volatile布尔值来中断线程,但是我可以将其用于其他目的。 (学习练习)。

第二个是Thread interrupt() does not interrupt thread/Stackoverflow link

还没有真正的帮助!。

我将尝试提供必要的代码,希望有人指出我的错误。

1)第一次尝试:

在这种尝试中,即使整个实验时间接近20秒,程序也不会停止。并且线程不会被终止也不会被中断。

private volatile Thread selfPhilosopher = this;


@Override
public void stopPhilosopher() {
    System.out.printf("\n%s will stop.\n",selfPhilosopher.getName());
    selfPhilosopher.interrupt();

}
/*
//Making a synchronized method didnt help either! :(.
private synchronized boolean isStopped(){
    return selfPhilosopher.isInterrupted();
}
*/
@Override
public void run() {
    while (!selfPhilosopher.isInterrupted()){//selfPhilosopher is a thread equals to this!.
        try {
                think();
                eat();
                //selfPhilosopher.sleep(100);//look at (**) at the end of the post!.
        } catch (InterruptedException e) {//somehow this was never triggered!.
            System.out.printf("%s was interrupted.\n",selfPhilosopher.getName());
        }finally {//in the finally block i always get RUNNER, **FALSE**
            System.out.printf("the %s is %s and is interrupted %b.\n", selfPhilosopher.getName(),selfPhilosopher.getState(), selfPhilosopher.isInterrupted());
        }
    }
}

run()stopPhilosopher()将由教授提供的代码调用,如下所示:

for (var i = 0; i < PHILOSOPHER_NUM; i++) {
        philosophers[i].start();
    }

    Thread.sleep(EXP_DURATION_MS);
    for (var i = 0; i < PHILOSOPHER_NUM; i++) {
        philosophers[i].stopPhilosopher();
    }

哲学家课是公开的,并且扩展了Thread!。

**)在练习中,不需要使线程休眠,但是当我在第二篇提供的帖子中看到有人@ user207421发表“线程仅在可中断操作期间被中断,例如Thread.sleep(),Thread。 wait()和一些I / O调用(不是全部)。”作为无望的尝试,我大声疾呼,但这并没有使它变得更好或更糟,它只是使线程休眠了一段时间。

如果需要,我可以为eat和思考方法提供代码,但我假设您已经知道其中的内容。 :)

2)第二次尝试:(遭到教授的拒绝,他不希望我们使用易失布尔值作为标志!)

当使用像这样的易失性布尔值时起作用:

private volatile boolean isNotStopped=true;

@Override
public void stopPhilosopher() {
    System.out.printf("\n%s will stop.\n",selfPhilosopher.getName());
    selfPhilosopher.interrupt();
    isNotStopped=false;
}


@Override
public void run() {
    while (isNotStopped){//selfPhilosopher is a thread equals to this!.
        try {
                think();
                eat();
        } catch (InterruptedException e) {//somehow this was never triggered!.
            System.out.printf("%s was interrupted.\n",selfPhilosopher.getName());
        }finally {//in the finally block i always get RUNNER, FALSE
            System.out.printf("the %s is %s and is interrupted %b.\n", selfPhilosopher.getName(),selfPhilosopher.getState(), selfPhilosopher.isInterrupted());
        }
    }
}

3)他们的尝试:

替换selfPhilosopher.isInterrupted()` with Thread.currentThread()。isInterrupted()didn't solve the problem. yet im getting stopped from the eat()`方法,但线程似乎像僵尸一样重生:(

为了更好地理解问题,我将在其中添加think()eat()方法,这些方法具有一些将触发run()中的catch子句的语句

请注意,由于线程永远不会在run()中终止,所以程序是无尽的,这是错误的

private void think() throws InterruptedException {
    System.out.printf("%s is Thinking.\n",selfPhilosopher.getName());
    Thread.sleep(this.random.nextInt(PhilosopherExperiment.MAX_THINKING_DURATION_MS));
}
private void eat() {
    System.out.printf("""

            %s is trying to eat!.
            """,selfPhilosopher.getName() );
    table.lock();

    try {

        if (firstToStartEating){
            System.out.printf("%s is the first to eat no and no one has been eating.\n", selfPhilosopher.getName() );
            //if first one to eat then no need to check for neighbors!.
            firstToStartEating=false;

        }else {
            //make both neighbors wait after checking if they are not eating!.
            System.out.printf("checking if the %s is eating!..->", ((Philosopher) left).getName());
            if (((Philosopher) left).getIsEating()) {
                ((Philosopher) left).getNeighborCondition().await();

            }
            System.out.printf("%s is is not eating.\n", ((Philosopher) left).getName());

            Thread.sleep(random.nextInt(PhilosopherExperiment.MAX_TAKING_TIME_MS));

            System.out.printf("checking if the %s is eating!..->", ((Philosopher) right).getName());
            if (((Philosopher) right).getIsEating()) {
                    ((Philosopher) left).getNeighborCondition().await();
            }
            System.out.printf("%s is is not eating.\n", ((Philosopher) right).getName());
        }


        System.out.printf("%s starting to eat.\n", selfPhilosopher.getName());

        this.setIsEating(true);
        Thread.sleep(PhilosopherExperiment.MAX_EATING_DURATION_MS);

        this.setIsEating(false);
        System.out.printf("%s finished eating.\n", selfPhilosopher.getName());
        this.getNeighborCondition().signalAll();//notify all that this professor finished eating.

    } catch (InterruptedException e) {
        System.out.println(selfPhilosopher.getName()+ " was interupted form eat!..\n");
    } finally {
        table.unlock();
    }
}

输出:

Philosopher1 in seat nr: 1 is trying to eat!.
Philosopher3 in seat nr: 3 finished eating.
checking if the Philosopher3 in seat nr: 3 is eating!..->Philosopher3 in seat nr: 3 is is not eating.
checking if the Philosopher5 in seat nr: 5 is eating!..->Philosopher5 in seat nr: 5 is is not eating.
Philosopher4 in seat nr: 4 starting to eat.
the Philosopher3 in seat nr: 3 is RUNNABLE and is interrupted false.
Philosopher3 in seat nr: 3 is Thinking.

Philosopher3 in seat nr: 3 is trying to eat!.

Philosopher1 in seat nr: 1 will stop.

Philosopher2 in seat nr: 2 will stop.

Philosopher3 in seat nr: 3 will stop.

Philosopher4 in seat nr: 4 will stop.

Philosopher5 in seat nr: 5 will stop.
Philosopher4 in seat nr: 4 finished eating.
checking if the Philosopher4 in seat nr: 4 is eating!..->Philosopher4 in seat nr: 4 is is not eating.
checking if the Philosopher1 in seat nr: 1 is eating!..->Philosopher1 in seat nr: 1 is is not eating.
Philosopher5 in seat nr: 5 starting to eat.
the Philosopher4 in seat nr: 4 is RUNNABLE and is interrupted false.
Philosopher4 in seat nr: 4 is Thinking.

Philosopher4 in seat nr: 4 is trying to eat!.

我正在尝试与著名的餐饮哲学家合作,并且已经完成,但是我在尝试中断线程方面遇到了很多困难。因此,如您所知,我们有5个线程(...

java multithreading interrupt
1个回答
0
投票

当引发InterruptedException时,将清除中断标志。这意味着您的循环进行的下一次检查将指示线程未中断,并且线程将继续运行。这就是当您的finally块为中断标志打印出false时所看到的。

the API doc for the sleep method中对此进行了描述:

© www.soinside.com 2019 - 2024. All rights reserved.