2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

javaの有効期限付きコレクション

Posted at

たとえばRedisだとエントリに有効期限を指定できる。おおむねそれで事足りるのだが、Java内でそういうこと出来るコレクションのライブラリが無いかを探す。

ソースコード

pom.xml
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>11</java.version>
	</properties>

	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-collections4</artifactId>
			<version>4.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>28.0-jre</version>
		</dependency>

	</dependencies>

Apache Commons CollectionsのPassiveExpiringMap

import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections4.map.PassiveExpiringMap;

public class App {
    public static void main(String[] args) throws InterruptedException {

        Map<String, String> map = new PassiveExpiringMap<String, String>(3000, TimeUnit.MILLISECONDS);
        map.put("key1", "value1");

        while (true) {
            TimeUnit.MILLISECONDS.sleep(1000);
            System.out.println(map.size());
        }
    }
}

上記を実行すると以下のようになる。

1
1
0

有効期限3秒。Passiveとあるとおりmapに特定の操作を行わない限り、期限切れのチェックは行わない。特定の操作とは https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/PassiveExpiringMap.html にあるとおりAll expired entries are removed from ...とかなんとか書いてあるヤツのこと。

Note that PassiveExpiringMap is not synchronized and is not thread-safeと書いてあるんでそこは注意が必要。

GuavaのCacheBuilder

import java.util.concurrent.TimeUnit;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

public class GuavaCaamain {

    public static void main(String[] args) throws InterruptedException {        
        Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(3000, TimeUnit.MILLISECONDS).build();
        cache.put("key1", "value1");
        
        while (true) {
            TimeUnit.MILLISECONDS.sleep(1000);
            cache.put("key2", "value2");
            System.out.println(cache.size());
        }

    }

}

上記を実行すると以下のようになる。

2
2
1

expireAfterWriteのとおり書き込み時に有効期限切れをチェックする。なので上記コードからputの行を消すとずっとキャッシュの内容は変わらない。

逆に読み込み時にチェックするには以下の通り。

Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(3000, TimeUnit.MILLISECONDS).build();

参考

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?