猿问

Java线程中断仅等待、加入和睡眠

Thread.interrupt():

中断该线程。除非当前线程正在中断自身(这始终是允许的),否则将调用该线程的 checkAccess 方法,这可能会导致抛出 SecurityException。

如果此线程在调用Object 类的 wait()、wait(long) 或 wait(long, int) 方法或 join()、join(long)、join(long, int) 时被阻止、 sleep(long) 或 sleep(long, int) 等此类方法,则其中断状态将被清除,并会收到 InterruptedException。

如果该线程在 InterruptibleChannel 上的I/O 操作中被阻塞,则该通道将被关闭,该线程的中断状态将被设置,并且该线程将收到 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()from ,从不在文件中写入任何内容thread2。


java.nio.channels.ClosedByInterruptException它总是以at结尾writer.newLine();并且foo.txt为空。


有没有办法只打断wait, join and sleep,而忽略其余的?


我在 Windows10 x64 上使用 JDK10 运行我的代码。


阿晨1998
浏览 135回答 2
2回答

慕森卡

如果您想要的是仅在线程被 wait、join 和 sleep 调用阻塞而不是 IO 操作时中断线程,您可以在调用中断方法之前简单地检查线程状态。您可以参考以下链接中的 api 和不同状态。https://docs.oracle.com/javase/10/docs/api/java/lang/Thread.State.html示例代码可能如下所示。while&nbsp;(&nbsp;(&nbsp;thread1.getState()&nbsp;==&nbsp;Thread.State.WAITING&nbsp;||&nbsp;thread1.getState()&nbsp;==&nbsp;Thread.State.TIMED_WAITING&nbsp;)&nbsp;&&&nbsp;!thread1Done.get())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;thread1.interrupt(); }

侃侃无极

按照目前的情况,您的代码运行完成将Thread 110k 行写入输出文本文件,换句话说是中断,但其中Thread 2没有可中断的语句。这是因为(我想)使用不间断 I/O打开文件。Thread 1BufferedWriter如果您希望长循环是Thread 1可中断的,您可以在长时间运行的循环中添加以下检查:for(int i = 0; i < 10000; i++){&nbsp; &nbsp; if (Thread.currentThread().isInterrupted()) {&nbsp; &nbsp; //interruptible loop&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; }&nbsp; &nbsp; writer.write(i);&nbsp; &nbsp; writer.newLine();&nbsp; &nbsp; System.out.println(i);}然后,通过将中断延迟Thread 210 毫秒,我发现只有几百个条目被写入文件(没有延迟,它会立即中断)。当我切换Thread 1为使用可中断通道时(按原样FileChannel extends AbstractInterruptibleChannel):Thread thread1 = new Thread(() -> {&nbsp; &nbsp; FileChannel fc = null;&nbsp; &nbsp; try (&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FileChannel fc = FileChannel.open(Paths.get("foo.txt"),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StandardOpenOption.CREATE, StandardOpenOption.WRITE);&nbsp; &nbsp; )&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;fc = FileChannel.open(Paths.get("foo.txt"),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StandardOpenOption.CREATE, StandardOpenOption.WRITE&nbsp; &nbsp; &nbsp; &nbsp;);&nbsp; &nbsp; &nbsp; &nbsp;for(int i = 0; i < 10000; i++){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fc.write(ByteBuffer.wrap(("" + i).getBytes()));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fc.write(ByteBuffer.wrap(("\n").getBytes()));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;System.out.println(i);&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; } catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp;e.printStackTrace();&nbsp; &nbsp; }&nbsp;}...我确实得到了很好的可中断文件写入线程。
随时随地看视频慕课网APP

相关分类

Java
我要回答