首页 > 解决方案 > 文件写入程序随机退出而没有错误

问题描述

目前我正在尝试使用 Java 的 Files-Class 写入 txt 文件。此任务应每 5 秒完成一次,并由 ScheduledExecutorService 安排。一段时间以来,它的工作正常,但在随机时间后,我的程序退出时没有任何警告、错误等。我试图重现这一点,但它似乎非常随机。我也尝试过使用 PrintWriter ,但这会随机导致相同的行为。

提前致谢!!!

这是我的代码:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class FileWritingClass
{
    public static void main(String[] args) throws IOException
    {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        scheduler.scheduleAtFixedRate(
            new Runnable() {
                long i;
                String str = "";
                Path path = Paths.get("TestFile.txt");

                @Override
                public void run() {

                    str = LocalTime.now().toString() + ": still alive after " + i + " times.";
                    i++;

                    try
                    {   
                        System.out.println(str);
                        Files.write(path, (str + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            },
            500 /* Startdelay */,
            5000 /* period */,
            TimeUnit.MILLISECONDS );        
    }
}

标签: javafile-ioscheduled-tasks

解决方案


正在吞咽除 之外的Executor异常IOException。抓住Throwable而不是仅仅IOException.

遇到除 IOException 以外的Executor其他异常时失败。虚拟机还活着,但Executor失败了。

这里有一些代码可以尝试:

                    try
                    {   
                        System.out.println(str);
                        Files.write(path, (str + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND);
                        if(new Random().nextBoolean()) {
                            System.out.println("Here we go.");
                            throw new RuntimeException("Uncaught");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch(Throwable t) {
                        t.printStackTrace();
                        System.out.println("The show must go on...");
                    }

请注意我如何在写入后给出 50/50 的机会抛出未捕获的异常(只是为了快速失败)。如果您删除第二个catch,它将停止打印。使用catch,输出变为:

12:46:00.780250700: still alive after 0 times.
12:46:05.706355500: still alive after 1 times.
Here we go.
java.lang.RuntimeException:
Uncaught at
KeepaTokenRecorder$FileWritingClass$1.run(KeepaTokenRecorder.java:89)
    at [...]
The show must go on...
12:46:15.705899200: still alive after 3 times.

推荐阅读