在Java中中断循环线程
我试图理解线程在Java中是如何工作的,目前正在研究如何实现可以取消的循环线程。代码如下:在Java中中断循环线程,java,multithreading,interrupted-exception,interruption,Java,Multithreading,Interrupted Exception,Interruption,我试图理解线程在Java中是如何工作的,目前正在研究如何实现可以取消的循环线程。代码如下: public static void main(String[] args) throws Exception { Thread t = new Thread() { @Override public void run() { System.out.println("THREAD: started"); try {
public static void main(String[] args) throws Exception {
Thread t = new Thread() {
@Override
public void run() {
System.out.println("THREAD: started");
try {
while(!isInterrupted()) {
System.out.printf("THREAD: working...\n");
Thread.sleep(100);
}
} catch(InterruptedException e) {
// we're interrupted on Thread.sleep(), ok
// EDIT
interrupt();
} finally {
// we've either finished normally
// or got an InterruptedException on call to Thread.sleep()
// or finished because of isInterrupted() flag
// clean-up and we're done
System.out.println("THREAD: done");
}
}
};
t.start();
Thread.sleep(500);
System.out.println("CALLER: asking to stop");
t.interrupt();
t.join();
System.out.println("CALLER: thread finished");
}
我创建的线程迟早会被中断。因此,我检查isInterrupted()标志以决定是否需要继续并捕获InterruptedException
,以处理处于等待操作中的情况(sleep
,join
,wait
)
我想澄清的是:
易失性布尔值相比应停止
)InterruptedException
捕获中的interrupt()
的调用。我回答的是第3个问题:
基本上,问题是:中断异常有什么用途?它告诉你停止阻塞(如睡觉),早点回来
有两种处理中断异常的方法:
- 重新旋转它,使线程保持中断状态
- 再次设置
,然后执行清理工作。这样,您可以确保线程中另一个开始休眠的方法将再次抛出Thread.currentThread.interrupt()
InterruptedException
并不是一个好主意,因为这样一个中断的目的是最终终止。但你只是被要求打断,所以你还有时间清理
在这种情况下,这可能是我自己的“过度反应”,但通常这样的代码要复杂得多,您如何知道,该线程中的一些后续代码不会再次调用阻塞方法
编辑
否则我认为你做的很好。不过,对我来说有点惊讶,因为我从来没有看到任何人在自己的代码中真正这么做
下面是一篇有趣的文章,解释了为什么会这样:
Thread.currentThread().interrupt()代码>
4) 不可以使用中断,但要好好使用它们。您必须在catch中重新抛出
Thread.currentThread().interrupt()
。下面是一段代码,说明了原因:
public class MyThread extends Thread {
private static boolean correct = true;
@Override
public void run() {
while (true) {
// Do Something 1
for (int i = 0; i < 10; i++) { // combined loop
// Do Something 2
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
if (correct)
Thread.currentThread().interrupt(); // reinterrupting
System.out.println("First Catch");
break; // for
}
}
try {
// Do Something 3
System.out.print("before sleep, ");
Thread.sleep(1000);
System.out.print("After sleep, ");
} catch (InterruptedException ex) {
if (correct)
Thread.currentThread().interrupt();
System.out.println("Second catch");
break; // while
}
}
System.out.println("Thread closing");
}
private static void test() throws InterruptedException {
Thread t = new MyThread();
t.start();
Thread.sleep(2500);
t.interrupt();
t.join();
System.out.println("End of Thread");
}
public static void main(String[] args)
throws InterruptedException {
test();
correct = false; // test "bad" way
test();
}
}
好吧,我相信重新引用不是一种情况,因为我不能从线程的
run()
中抛出。是否应调用中断()?isInterrupted不会重置中断标志。如何在不中断的情况下阻止线程长时间等待或休眠?没关系,但最好不要扩展线程,因为它没有扩展其功能。实现一个可运行线程,供标准线程使用。
public class Mythread extends Thread {
private InputStream in;
public Mythread(InputStream in) {
this.in = in;
}
@Override
public void interrupt() {
super.interrupt();
try {
in.close(); // Close stream if case interruption didn't work
} catch (IOException e) {}
}
@Override
public void run() {
try {
System.out.println("Before read");
in.read();
System.out.println("After read");
} catch (InterruptedIOException e) { // Interruption correctly handled
Thread.currentThread().interrupt();
System.out.println("Interrupted with InterruptedIOException");
} catch (IOException e) {
if (!isInterrupted()) { // Exception not coming from Interruption
e.printStackTrace();
} else { // Thread interrupted but InterruptedIOException wasn't handled for this stream
System.out.println("Interrupted");
}
}
}
public static void test1() // Test with socket
throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(4444);
Socket socket = new Socket("localhost", 4444);
Thread t = new Mythread(socket.getInputStream());
t.start();
Thread.sleep(1000);
t.interrupt();
t.join();
}
public static void test2() // Test with PipedOutputStream
throws IOException, InterruptedException {
PipedInputStream in = new PipedInputStream(new PipedOutputStream());
Thread t = new Mythread(in);
t.start();
Thread.sleep(1000);
t.interrupt();
t.join();
}
public static void main(String[] args) throws IOException, InterruptedException {
test1();
test2();
}
}