定期保存/刷新/提交 - 这种模式有名称吗?

发布于 2024-10-09 20:45:55 字数 1592 浏览 9 评论 0原文

我发现自己一次又一次面临类似的问题:有一些代码可以处理来自用户/网络/某种产品的数据。出于效率原因,我不想对收到的每条数据调用 flush()commit(),但只是偶尔调用。

我通常会想出这样的代码:

class Processor {
    private final static MAX_SAVE_PERIOD = 60000;
    private final static MIN_SAVE_PERIOD = 20000;

    private final static int MAX_BUFFER = 10000;
    Arraylist<Data> dataBuffer = new Arraylist<Data>();

    private long lastSave = 0;

    public Saver() {
        new Timer().schedule(new TimerTask() {
            periodicSave();
        }, MAX_SAVE_PERIOD, MAX_SAVE_PERIOD);
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                periodicSave();
            }
        }));
    }

    public synchronized void processData(Data data) {
        dataBuffer.add(data);
        if(dataBuffer.size() >= MAX_BUFFER) {
            saveData();
        }
    }

    private synchronzied void periodicSave() {
        if(!dataBuffer.isEmpty()) {
            saveData();
        }
    }

    private void saveData() {
        if (System.currentTimeMillis() - lastSave < MIN_SAVE_PERIOD) return;

        ...        

        lastSave = System.currentTimeMillis();
    }
}

每次写这个代码时,我都会有一种明显的感觉,那就是我在重新发明轮子,而且,每次写这种代码时,我都会不断地改变东西,这取决于各个部分是否使具体语境中的意义。

在我看来,这是一种非常常见的模式,但我不记得看到它被命名或实现为库实用程序。只要我必须自己实现这个,每当我重新实现它时,我都会面临分析瘫痪。请帮我!

更新:写完这篇文章后,我意识到我没有考虑到在 JVM 关闭之前刷新缓冲区,所以我在构造函数中添加了一个关闭钩子。现在我意识到,如果上次保存后关闭时间少于 MIN_SAVE_PERIOD 毫秒,此代码仍然无法正常工作,因此我可能应该重构 saveData。它又发生了。

I find myself again and again faced with a similar problem: there's some piece of code that processes data as it arrives from the user/network/produces of some sort. For efficiency reasons, I don't want to call flush() or commit() on every piece of data that I receive, but only occasionally.

I usually come up with code like this:

class Processor {
    private final static MAX_SAVE_PERIOD = 60000;
    private final static MIN_SAVE_PERIOD = 20000;

    private final static int MAX_BUFFER = 10000;
    Arraylist<Data> dataBuffer = new Arraylist<Data>();

    private long lastSave = 0;

    public Saver() {
        new Timer().schedule(new TimerTask() {
            periodicSave();
        }, MAX_SAVE_PERIOD, MAX_SAVE_PERIOD);
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                periodicSave();
            }
        }));
    }

    public synchronized void processData(Data data) {
        dataBuffer.add(data);
        if(dataBuffer.size() >= MAX_BUFFER) {
            saveData();
        }
    }

    private synchronzied void periodicSave() {
        if(!dataBuffer.isEmpty()) {
            saveData();
        }
    }

    private void saveData() {
        if (System.currentTimeMillis() - lastSave < MIN_SAVE_PERIOD) return;

        ...        

        lastSave = System.currentTimeMillis();
    }
}

I get the distinct feeling that I'm reinventing the wheel every time I write this, and what's more, I keep changing stuff every time I write this kind of code, depending if the various parts make sense in the specific context.

It seems to me that this is a very common pattern, but I don't remember seeing it named or implemented as a library utility. As long as I have to implement this myself, I keep facing analysis paralysis whenever I reimplement it. Please help me!

UPDATE: After I wrote this, I realized that I haven't accounted for flushing the buffer before JVM shutdown, so I added a shutdown hook in the constructor. Now I've realized that this code will still not work properly if the shutdown happens less than MIN_SAVE_PERIOD milliseconds after the last save, so I should probably refactor saveData. It's happening again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柳若烟 2024-10-16 20:45:55

您的代码已经说明了这一点:它称为缓冲

Your code already says it: it's called buffering.

海夕 2024-10-16 20:45:55

生产者/消费者通过有界缓冲区。请参阅生产者消费者问题

Producer / consumer via a bounded buffer. See Producer consumer problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文