【问题标题】:periodic save/flush/commit - is there a name to this pattern?定期保存/刷新/提交 - 这种模式有名称吗?
【发布时间】:2011-01-02 14:30:57
【问题描述】:

我发现自己一次又一次地面临着类似的问题:当数据从用户/网络/某种产品到达时,有一段代码会处理数据。出于效率原因,我不想在收到的每条数据上都调用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。它又发生了。

【问题讨论】:

    标签: java flush


    【解决方案1】:

    你的代码已经说过了:它叫做buffering

    【讨论】:

    • 谷歌搜索“缓冲模式”和“缓冲习语”不会产生任何有趣的结果。这是因为这是一种无趣的模式吗?
    • 维基百科似乎有一个很好的通用定义:en.wikipedia.org/wiki/Data_buffer
    【解决方案2】:

    生产者/消费者通过有界缓冲区。见Producer consumer problem

    【讨论】:

      猜你喜欢
      • 2010-11-21
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 1970-01-01
      • 2011-04-23
      相关资源
      最近更新 更多