为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

阿晨1998 2023-10-19 21:53:37
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 fileThread 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 thread1Thread 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 运行我的代码。
查看完整描述

2 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

如果您想要的是仅在线程被 wait、join 和 sleep 调用阻塞而不是 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();
}


查看完整回答
反对 回复 2023-10-19
?
侃侃无极

TA贡献2051条经验 获得超10个赞

按照目前的情况,您的代码运行完成将Thread 110k 行写入输出文本文件,换句话说是中断,但其中Thread 2没有可中断的语句。这是因为(我想)使用不间断 I/O打开文件。Thread 1BufferedWriter


如果您希望长循环是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 210 毫秒,我发现只有几百个条目被写入文件(没有延迟,它会立即中断)。


当我切换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();

    } 

}

...我确实得到了很好的可中断文件写入线程。


查看完整回答
反对 回复 2023-10-19
  • 2 回答
  • 0 关注
  • 134 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信