尽管捕获异常

时间:2017-12-12 13:14:24

标签: java multithreading

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

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

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

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

@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然后打印出来{ {1}}并停止..为什么会这样?

3 个答案:

答案 0 :(得分:2)

当在withdrawal中捕获到异常时,它会返回带有返回的方法,因此异常处理将在那里结束。

更新:

如果您想继续处理InterruptedException方法之外的withdrawal,可以执行以下操作:

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

    {...}

    notifyAll();

}

答案 1 :(得分:1)

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

您应该使用throw new InterruptedException(ex.getMessage());

替换return

此外,如果您在提款方法中不使用try catch,它也会按照您的意图执行。

答案 2 :(得分:1)

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

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

}