9

私の使用例は、永続的な DB に格納されたデータに対してインメモリ キャッシュを維持することです。

データを使用して、UI にエントリのリスト/マップを設定します。任意の時点で、UI に表示されるデータは可能な限り更新する必要があります (これはキャッシュの更新頻度によって行うことができます)。

通常のキャッシュ実装とこの特定のキャッシュの主な違いは、すべての要素を定期的に一括更新する必要があるため、LRU の種類のキャッシュとはかなり異なることです。

私は Java でこの実装を行う必要があります。これを構築するために利用できる既存のフレームワークがあれば、それは素晴らしいことです。

Google Guava キャッシュ ライブラリを調査しましたが、一括更新よりもエントリごとの更新に適しています。キャッシュ全体を更新する単純な API はありません。

どんな助けでも大歓迎です。

また、キャッシュ全体をリフレッシュする際に発生する唯一の制限は、キャッシュのサイズが非常に大きい場合、メモリ ヒープは少なくとも新しいエントリをロードし、古いマップを新しいマップに置き換えるためにキャッシュします。キャッシュがインクリメンタルであるか、チャンク リフレッシュ (等しいサイズでのリフレッシュ) がある場合、それは素晴らしいことです。

4

3 に答える 3

3

EHCacheは、かなりフル機能の Java キャッシング ライブラリです。私は彼らがあなたのために働く何かを持っていると思います.

キャッシュのインクリメンタル リロードを実行するには (ほとんどのキャッシュで機能します)、現在ロードされているエントリを繰り返し処理し、それらを強制的に更新します。(バックグラウンド スケジューラでこのタスクを実行できます)。

キャッシュ全体を強制的にリロードする代わりに、EHCache にはエントリの「存続時間」を指定する機能があるため、エントリが古すぎる場合は自動的にリロードされます。

于 2012-10-05T14:05:08.817 に答える
0

このクラスを継承し、増分更新を取得するために loadDataFromDB と updateData を実装するだけです

import org.apache.log4j.Logger;
import java.util.List;
import java.util.concurrent.Semaphore;


public abstract class Updatable<T>
{
    protected volatile long lastRefreshed = 0;
    private final int REFRESH_FREQUENCY_MILLISECONDS = 300000; // 5 minutes
    private Thread updateThread;
    private final Semaphore updateInProgress = new Semaphore(1);

    protected static final Logger log = Logger.getLogger(Updatable.class);

    public void forceRefresh()
    {
        try
        {
            updateInProgress.acquire();
        }
        catch (InterruptedException e)
        {
            log.warn("forceRefresh Interrupted");
        }

        try
        {
            loadAllData();
        }
        catch (Exception e)
        {
            log.error("Exception while updating data from DB", e);
        }
        finally
            {
            updateInProgress.release();
        }

    }

    protected void checkRefresh()
    {
        if (lastRefreshed + REFRESH_FREQUENCY_MILLISECONDS <     System.currentTimeMillis())
            startUpdateThread();
    }

    private void startUpdateThread()
    {
        if (updateInProgress.tryAcquire())
        {
            updateThread = new Thread(new Runnable()
            {
                public void run()
                {
                    try
                    {
                        loadAllData();
                    }
                    catch (Exception e)
                    {
                        log.error("Exception while updating data from DB", e);
                    }
                    finally
                    {
                        updateInProgress.release();
                    }
                }
            });

            updateThread.start();
        }
    }

    /**
     * implement this function to load the data from DB
     *
     * @return
     */
    protected abstract List<T> loadFromDB();

    /**
     * Implement this function to hotswap the data in memory after it was loaded from DB
     *
     * @param data
     */
    protected abstract void updateData(List<T> data);

    private void loadAllData()
    {
        List<T> l = loadFromDB();
        updateData(l);
        lastRefreshed = System.currentTimeMillis();
    }

    public void invalidateCache()
    {
         lastRefreshed = 0;
    }

}
于 2012-10-05T13:22:34.720 に答える