1

クラスの最初にロードする静的変数があります。変数を1時間ごとに更新したい。問題は、これを行う適切な方法は何ですか?

私がやろうとしている方法は次のとおりですが、静的変数を更新するメソッドがすべてのコンストラクターにある必要があります。

import java.util.Date;

public class MyClass {

    private static String globalString = "";

    // initialize lastUpdate with two hours back to make sure first update happens
    private static Date lastUpdate = new Date(System.currentTimeMillis() - (2 * (3600 * 1000)));


    MyClass() {
        updateGlobalString();

        // DO MORE STUFF HERE...
    }


    MyClass(String string) {
        updateGlobalString();

        // DO MORE STUFF HERE...
    }

    private synchronized void updateGlobalString() {
        // check if we need to update
        if (lastUpdate.before(new Date(System.currentTimeMillis() - (3600 * 1000)))) {

            // DO THINGS TO UPDATE globalString HERE...

            lastUpdate = new Date();
        }
    }
}

他のアイデア/より良い方法はありますか?

4

2 に答える 2

5

更新を行うには、ある種のタイマーを使用する必要があります。

たとえば、ScheduledExecutorService を使用して、フィールドを更新するタスクを 1 時間ごとに実行します。このようなもの:

public class MyClass {

    private static volatile String globalString;
    private static ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();

    static {
        exec.scheduleAtFixedRate(new Runnable() {
            public void run() {
               // DO THINGS TO UPDATE globalString HERE...
            }
        },
        0, 1, TimeUnit.HOUR);
    }

    // Rest of class, without having to worry about the updateGlobalString
    // method, or the lastUpdate variable, or anything like that
    ...
}

変数は複数のスレッドによってアクセスされるため、コードがスレッドセーフであることを確認する必要があることに注意してください。(これは間違いなく上記のタイマーの例に当てはまりますが、現在のアプローチにも当てはまる可能性があります。)

更新が表示されるようにする最も簡単な方法は、globalString変数を としてマークすることですvolatileが、クラスの使用方法によっては、他のアプローチがより適切な場合があります。

于 2013-05-09T16:21:31.000 に答える
1

簡単な解決策は、Executors フレームワークを使用することです。

public class MyClass {
   public static String globalString = "";

   private static ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();

   //static block of code
   static {
     s.scheduleAtFixedRate(new Runnable() {
        public void run() {
           globalString = System.currentTimeMillis() + "";
        }
     }, 0, 1, TimeUnit.HOUR);
   } 
}
于 2013-05-09T16:24:16.207 に答える