Thread.interrupt()
:
中断此线程。除非当前线程 正在中断自身(始终允许),checkAccess 调用此线程的方法,这可能会导致SecurityException 被扔掉。
如果在调用 wait(),wait(long), 或Object类或join()的wait(long,int)方法, join(long),join(long,int),sleep(long)或sleep(long,int),方法 此类,则将清除其中断状态并将其 收到InterruptedException。
如果此线程在 I / O操作中被阻止, 然后中断InterruptibleChannel,将关闭该线程的 中断状态将被设置,线程将收到一个 ClosedByInterruptException。
如果此线程在选择器中被阻止,则该线程的中断 状态将被设置,它将立即从选择中返回 操作,可能具有非零值,就像选择器的 唤醒方法被调用。
如果先前的条件均不成立,则此线程的中断 状态将被设置。
中断未运行的线程不会产生任何效果。
让我们说我们有以下代码:
AtomicBoolean thread1Done = new AtomicBoolean(false);
//write in file
Thread thread1 = new Thread(() -> {
try(var writer = Files.newBufferedWriter(Paths.get("foo.txt"))){
for(int i = 0; i < 10000; i++){
writer.write(i);
writer.newLine();
}
}catch(Exception e){ e.printStackTrace(); }
thread1Done.set(true);
});
//interrupt thread1
Thread thread2 = new Thread(() -> {
while(!thread1Done.get()){
thread1.interrupt();
}
});
thread2.start();
thread1.start();
thread1
永远不会在文件中写入任何内容,因为thread1.interrupt()
中的thread2
。
它始终以java.nio.channels.ClosedByInterruptException
的{{1}}结尾,writer.newLine();
为空。
是否可以仅中断foo.txt
并忽略其余部分?
我在Windows10 x64上使用JDK10运行代码。
答案 0 :(得分:1)
按目前的情况运行代码,以使Thread 1
完成向输出文本文件中写入10k行的操作,换言之Thread 2
中断,但是Thread 1
中没有以下语句: strong>可中断。这是因为(我想)BufferedWriter
使用不间断I / O 打开文件。
如果您希望Thread 1
中的长循环是可中断的,则可以在长循环中添加以下检查:
for(int i = 0; i < 10000; i++){
if (Thread.currentThread().isInterrupted()) { //interruptible loop
break;
}
writer.write(i);
writer.newLine();
System.out.println(i);
}
然后,将Thread 2
的中断延迟10毫秒,我得到的是只有几百个条目被写入文件(没有延迟,它会立即被中断)。
当我交换Thread 1
以使用可中断频道
(与FileChannel extends AbstractInterruptibleChannel
一样)时:
Thread thread1 = new Thread(() -> {
FileChannel fc = null;
try (
FileChannel fc = FileChannel.open(Paths.get("foo.txt"),
StandardOpenOption.CREATE, StandardOpenOption.WRITE);
)
{
fc = FileChannel.open(Paths.get("foo.txt"),
StandardOpenOption.CREATE, StandardOpenOption.WRITE
);
for(int i = 0; i < 10000; i++){
fc.write(ByteBuffer.wrap(("" + i).getBytes()));
fc.write(ByteBuffer.wrap(("\n").getBytes()));
System.out.println(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
...我确实得到了很好的可中断文件写入线程。
答案 1 :(得分:1)
如果您想要的是仅在等待,联接和睡眠调用而不是IO操作阻止的情况下中断线程,则可以在调用中断方法之前简单地检查线程状态。您可以参考api和以下链接中的不同状态。
https://docs.oracle.com/javase/10/docs/api/java/lang/Thread.State.html
示例代码可能类似于下面的代码。
while ( ( thread1.getState() == Thread.State.WAITING || thread1.getState() == Thread.State.TIMED_WAITING ) && !thread1Done.get()) {
thread1.interrupt();
}