One, the introduction

The system often exposes some special data, which is stored in a relational database and has the following characteristics:

  • Frequent data requests
  • The data changes very little
  • The data volume is slightly larger

If data requests are frequent, frequent interactions with the database occupy session resources of the database. In addition, the data volume is slightly larger and requires a large number of channels for data transmission. The data changes very little, indicating that the data is almost static. In general, when faced with this scenario, we think of upper cache, such as Redis, Memcached, Caffeine. But in the spirit of keeping things simple without introducing them, I tried to implement a simple “cache” using Java static variables.

Second, the implementation

The following codes are used to implement static, AtomicReference, and SoftReference.

Suppose the business scenario is to cache administrative region information.

Define a regional entity

@Setter
@Getter
@Builder
public class RegionEntity {

    private long id;

    private String provinceName;

    private String provinceCode;
}
Copy the code

The collection entity of the wrapper region

@Getter
@Setter
@AllArgsConstructor
public class DictRegionDTO {

    private List<RegionEntity> regionList;
}
Copy the code

Gets the service interface for the region

public class DictService { static final AtomicReference<SoftReference<DictRegionDTO>> regionCache = new AtomicReference<>(); /** * fetch all of region * @return region all */ public Optional<DictRegionDTO> fetchRegion(){ if(regionCache.get() ! =null && regionCache.get().get() ! =null ){ return Optional.ofNullable(regionCache.get().get()); } //todo fetch by repository,return @NotNull value final DictRegionDTO dictRegionDTO = new DictRegionDTO(new ArrayList<>()); regionCache.set(new SoftReference<>(dictRegionDTO)); return Optional.of(dictRegionDTO); }}Copy the code

Static, ensuring that this variable is shared globally. Note that after JDK8 static variables are stored on the JVM heap.

AtomicReference guarantees atomic operation when using variables in multithreaded environment, and realizes atomic update of object references.

SoftReference is a SoftReference of an object. If an object has a SoftReference and there is enough memory, the GC will not reclaim it. If you run out of memory, the GC reclaims the memory of those objects.

SoftReference is used to prevent insufficient heap memory due to a large amount of data in the cache.

Third, summary

Of course, this is implemented so as not to introduce new components and increase the development and maintenance costs of the system. If your system has the need to use third-party caching, such as the need for persistent, distributed, caching special policies, so boldly use third-party caching!