Мне нужно хранить значения ArrayList, которые часто меняются, и сохранять эти значения в случае приложения cra sh. Приложение, над которым я работаю, уже использует базу данных Redis, так что оно показалось мне хорошим выбором.
Ниже я продемонстрировал минимальный пример контроллера с загрузочной пружиной, который подключается к экземпляру Redhost localhost и использует его для хранения сериализованных объектов. Значение можно изменить из конечной точки контроллера или с помощью запланированного задания, которое выполняется каждые 5 секунд. Если вы выполните серию запросов get к localhost:8080/test
, вы увидите, что запланированное задание удаляет элементы из ArrayList по одному.
Возможно ли пропустить значение или что-то еще? не потокобезопасно случиться здесь? Я обеспокоен тем, что запланированное задание может конфликтовать с изменениями, внесенными из конечной точки контроллера, если они попытаются изменить объект или одновременно установить значение Redis, особенно если сеть замедляется, но я не уверен, будет ли это на самом деле проблема. Кажется, все работает нормально, так как работает на моем локальном хосте, но я скептически отношусь.
Я прочитал эту статью, в частности, о безопасности потоков, но он не ответил, если какой-либо из эти вещи даже необходимы для этой конкретной ситуации. Я также знаю, что Redis для чтения и записи - это атомы c, но я подумал, что если команды будут отправлены в Redis в неправильном порядке?
Я думал, что если у этой реализации есть проблемы, тогда аннотация @Syncronized от Lombok может быть полезна для абстрагированного метода IO. Я ценю любой вклад и потраченное время.
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
@RestController
public class Example {
RedisClient redisClient = RedisClient.create("redis://localhost:6379/");
StatefulRedisConnection<String, String> connection = redisClient.connect();
RedisCommands<String, String> redis = connection.sync();
Gson gson = new Gson();
ArrayList<String> someList = new ArrayList<>();
public Example() {
if(redis.exists("somekey") == 1){
Type collectionType = new TypeToken<Collection<VideoDAO>>(){}.getType();
someList = new ArrayList<>(gson.fromJson(redis.get("somekey"), collectionType));
}
}
@GetMapping("/test")
public void addToSomeList(){
someList.add("sample string");
redis.set("somekey",gson.toJson(someList));
System.out.println("New item added. " + someList.size() + " items in array");
}
@Scheduled(fixedRate = 5000)
public void popFromSomeList() {
if (!someList.isEmpty()) {
someList.remove(0);
redis.set("somekey", gson.toJson(someList));
System.out.println("Item removed. " + someList.size() + " items in array");
}
}
}
Я использую java 1.8.