线程中断。有人可以向我解释输出以更好地理解中断吗?
Thread Interrupts. Can someone explain me the output to understand interrupts better?
我能够理解线程和中断。我试图映射从 Oracle 教程中学到的基本概念,以更好地理解中断的概念。我开发了这个例子,并努力理解输出是如何中断在这里发挥作用的。我只是不明白。所以我的想法是请人帮助我理解这个程序的输出,这将使我更清楚中断的基本功能。
public class ThreadSleepTest {
public static void main(String[] args) throws InterruptedException {
MyRunnable myRunnable = new MyRunnable();
Thread one = new Thread(myRunnable);
one.setName("Fred");
Thread two = new Thread(myRunnable);
two.setName("Lucy");
Thread three = new Thread(myRunnable);
three.setName("Ricky");
one.start();
two.start();
three.start();
//Thread.sleep(1000);
one.interrupt();
}
}
class MyRunnable implements Runnable {
public void run() {
for (int x = 1; x < 4; x++) {
System.out.println("Run by: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.out.println("Exception occured");
}
}
System.out.println("Do something");
}
}
这是我的控制台的输出。
Run by: Lucy
Run by: Fred
Run by: Ricky
Exception occured
Run by: Fred
Run by: Fred
Run by: Lucy
Run by: Ricky
Do something
Run by: Lucy
Run by: Ricky
Do something
Do something
如果您中断了一个线程,那么您在该线程中休眠或等待的下一次或当前时间将抛出 InterruptedException。但是中断状态被清除了。如果您的 Thread 被中断,您应该在不久的将来终止它。
中断一个线程意味着向它发出停止当前正在做的事情的信号。
大多数 I/O 和锁定操作将在 运行 上的线程被中断并且在该线程中引发 InterruptedException
时中断(但是,并非所有操作都这样做,因为示例参见 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquireUninterruptibly()).
然后代码能够以 he/she 认为合适的任何方式处理异常。 InterruptedException
引发后,中断信号被消耗,线程可以继续做任何事情。在您的示例中, Thread.sleep()
调用提前完成,抛出 InterruptedException 并记录一条消息。之后,线程继续 for
循环。当然后面可以打断线程。
Once a thread is interrupted, it is basically taken out of operation as per my understanding.
不对,你的理解有误。一旦线程被中断,由编写run
方法的程序员决定如何处理。
线程终止完全取决于程序员,因为 JVM 实际上不知道在终止线程时可能需要清除哪些资源和锁。这就是 Thread
中的方法 stop()
和 suspend()
被弃用的原因。他们不安全。
所以当一个线程被中断时,如果你在一个抛出InterruptedException
的方法中,你必须对这个异常做出反应并完成你正在做的任何事情,如果你在中间自己的东西,得时不时的查看一下当前线程的interrupted()
状态,如果有中断,就把正在做的事情做完。
这是您在线程中断时选择执行的操作:
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.out.println("Exception occured");
}
在您的 catch
子句中,您只是打印发生异常的事实。您实际上并没有为线程的终止做任何事情。因此,它不会被终止。您将退出 catch 子句,并继续循环的下一次迭代。
Thread.sleep()
按照惯例在抛出 InterruptedException
时清除中断标志。所以在下一次迭代中,线程不再是"interrupted",sleep()
也不会再次抛出异常
我认为 Java 并发实践 (JCiP),第 138 页对可能发生的情况给出了相当好的解释。您可以注意以下几点:
- 主线程创建并启动了 3 个名为:Fred、Lucy、Ricky 的线程。我们只考虑名为 Fred 的线程,它被分配给变量
one
(有更好的方法可以做到这一点,例如 CountdownLatch)。
- Fred,在被安排到 运行 之后,您的代码会立即让他入睡。方法
Thread.sleep
是一个精心设计的 阻塞调用 。这意味着它可以通过发送中断来中断。这正是主线程试图做的:请求中断 activity 线程 one
正在做或不做的事情(因为在这种情况下它只是在睡觉)。 main
线程通过简单地调用 one
上的 interrupt()
方法来做到这一点。请注意,这仅被中断的线程视为 'friendly request'。
- 在您看到输出 'Exception occurred' 的情况下,(睡眠中的)中断线程确认了中断,并且像记录的那样,抛出 InterruptedException。此异常被
one
捕获,消息 'Exception occurred' 打印在标准输出上。因此,主线程 已成功中断 one
正在做的事情 。
- 其他线程不间断地执行任务(这就是您看到其他打印语句的原因)。
我能够理解线程和中断。我试图映射从 Oracle 教程中学到的基本概念,以更好地理解中断的概念。我开发了这个例子,并努力理解输出是如何中断在这里发挥作用的。我只是不明白。所以我的想法是请人帮助我理解这个程序的输出,这将使我更清楚中断的基本功能。
public class ThreadSleepTest {
public static void main(String[] args) throws InterruptedException {
MyRunnable myRunnable = new MyRunnable();
Thread one = new Thread(myRunnable);
one.setName("Fred");
Thread two = new Thread(myRunnable);
two.setName("Lucy");
Thread three = new Thread(myRunnable);
three.setName("Ricky");
one.start();
two.start();
three.start();
//Thread.sleep(1000);
one.interrupt();
}
}
class MyRunnable implements Runnable {
public void run() {
for (int x = 1; x < 4; x++) {
System.out.println("Run by: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.out.println("Exception occured");
}
}
System.out.println("Do something");
}
}
这是我的控制台的输出。
Run by: Lucy
Run by: Fred
Run by: Ricky
Exception occured
Run by: Fred
Run by: Fred
Run by: Lucy
Run by: Ricky
Do something
Run by: Lucy
Run by: Ricky
Do something
Do something
如果您中断了一个线程,那么您在该线程中休眠或等待的下一次或当前时间将抛出 InterruptedException。但是中断状态被清除了。如果您的 Thread 被中断,您应该在不久的将来终止它。
中断一个线程意味着向它发出停止当前正在做的事情的信号。
大多数 I/O 和锁定操作将在 运行 上的线程被中断并且在该线程中引发 InterruptedException
时中断(但是,并非所有操作都这样做,因为示例参见 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquireUninterruptibly()).
然后代码能够以 he/she 认为合适的任何方式处理异常。 InterruptedException
引发后,中断信号被消耗,线程可以继续做任何事情。在您的示例中, Thread.sleep()
调用提前完成,抛出 InterruptedException 并记录一条消息。之后,线程继续 for
循环。当然后面可以打断线程。
Once a thread is interrupted, it is basically taken out of operation as per my understanding.
不对,你的理解有误。一旦线程被中断,由编写run
方法的程序员决定如何处理。
线程终止完全取决于程序员,因为 JVM 实际上不知道在终止线程时可能需要清除哪些资源和锁。这就是 Thread
中的方法 stop()
和 suspend()
被弃用的原因。他们不安全。
所以当一个线程被中断时,如果你在一个抛出InterruptedException
的方法中,你必须对这个异常做出反应并完成你正在做的任何事情,如果你在中间自己的东西,得时不时的查看一下当前线程的interrupted()
状态,如果有中断,就把正在做的事情做完。
这是您在线程中断时选择执行的操作:
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.out.println("Exception occured");
}
在您的 catch
子句中,您只是打印发生异常的事实。您实际上并没有为线程的终止做任何事情。因此,它不会被终止。您将退出 catch 子句,并继续循环的下一次迭代。
Thread.sleep()
按照惯例在抛出 InterruptedException
时清除中断标志。所以在下一次迭代中,线程不再是"interrupted",sleep()
也不会再次抛出异常
我认为 Java 并发实践 (JCiP),第 138 页对可能发生的情况给出了相当好的解释。您可以注意以下几点:
- 主线程创建并启动了 3 个名为:Fred、Lucy、Ricky 的线程。我们只考虑名为 Fred 的线程,它被分配给变量
one
(有更好的方法可以做到这一点,例如 CountdownLatch)。 - Fred,在被安排到 运行 之后,您的代码会立即让他入睡。方法
Thread.sleep
是一个精心设计的 阻塞调用 。这意味着它可以通过发送中断来中断。这正是主线程试图做的:请求中断 activity 线程one
正在做或不做的事情(因为在这种情况下它只是在睡觉)。main
线程通过简单地调用one
上的interrupt()
方法来做到这一点。请注意,这仅被中断的线程视为 'friendly request'。 - 在您看到输出 'Exception occurred' 的情况下,(睡眠中的)中断线程确认了中断,并且像记录的那样,抛出 InterruptedException。此异常被
one
捕获,消息 'Exception occurred' 打印在标准输出上。因此,主线程 已成功中断one
正在做的事情 。 - 其他线程不间断地执行任务(这就是您看到其他打印语句的原因)。