繁体   English   中英

尽管捕获到异常,线程仍然运行

[英]Thread still runs despite catching an exception

我有5个线程; 主(代表银行)和我创建的其他4个自定义线程(客户)。 每个自定义线程的run方法中都有大约6条指令,这些指令在共享资源/监视器上执行一个方法。 我将发布相关代码以使其简短而简单。 我要做的是在所有线程完成执行后显示一条消息。 在我的情况下,其中一个线程很容易陷入死锁并要克服死锁,因此我迫使主线程休眠一定的时间,以使所有线程有机会完成执行,一旦主线程醒来,它将检查如果其他线程还活着..如果是,则使用.interrupt()方法引发异常。 现在,我期望发生的是捕获中断的线程进入terminated状态,但奇怪的是,它没有并且仍然保持其运行状态。 我注意到的是,它继续在其run方法中执行语句,但是在使它进入wait状态的语句之后。

在主线程中,我检查clientB线程是否处于活动状态,如果是,则抛出异常。

   if(clientB.isAlive()){
        clientB .interrupt();
    }

ClientB的运行方法是一种简单的基本运行方法,可从监视器调用方法。

@Override
public void run() {
    System.out.println(threadName + " is in ThreadGroup: " + threadGroupName);
    threadState = Student.currentThread().getState().name();
    System.out.println("State of studentThread: " + threadState);
    Random rnd = new Random();

    try {

        Code number 1
        {...}

        Code number 2
        {...}

        Code number 3
        {...}

        Code number 4
        {...}

        Code number 5
        {...}
        System.out.println("ClientB Terminating");
    } catch (InterruptedException ex) {
        ex.printStackTrace();
        System.out.println("ClientB got interuppted.");
        return;
    }
}

如您所见,ClientB的run方法中没有任何while循环或任何东西。 这是ClientB调用的监视方法:

@Override
public synchronized void withdrawal(Transaction t) {
    while (t.getAmount() > this.balance) {
        try {
            wait();
        } catch (InterruptedException ex) {
            System.out.println("Withdrawal method interuppted.");
            return;
        }
    }

    {...}

    notifyAll();

}

现在,当我为所有线程提供10秒的主方法以完成其操作时,除了该方法的代码2上的ClientB之外,所有其他线程似乎都在该时间内完成,并且在调用中断后,我希望该线程能够捕获该异常并被杀死,但我注意到的是提现Withdrawal method interrupted. 在控制台上打印出来,但ClientB got interrupted. 然后完成执行代码3,4,5的操作,然后打印出ClientB Terminating并停止。

当异常被withdrawal捕获时,它以返回值退出方法,因此异常的处理在此处结束。

更新:

如果要在withdrawal方法之外继续处理InterruptedException ,则可以执行以下操作:

@Override
public synchronized void withdrawal(Transaction t) throws InterruptedException {
    while (t.getAmount() > this.balance) {
        wait();
    }

    {...}

    notifyAll();

}

是的,莫里斯是对的。 您不会将异常传递给调用方法。

您应该用throw new InterruptedException(ex.getMessage());替换return throw new InterruptedException(ex.getMessage());

同样,如果您不在提款方法中使用try catch,它也会按照您的意图进行操作。

为了在多个地方捕获相同的异常,应重新抛出它,例如:

@Override
public synchronized void withdrawal(Transaction t) throws InterruptedException {
    while (t.getAmount() > this.balance) {
        try {
            wait();
        } catch (InterruptedException ex) {
            System.out.println("Withdrawal method interuppted.");
            throw ex;
        }
    }

    {...}

    notifyAll();

}

暂无
暂无

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

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