2012-04-24 4 views
0

Я использую клиент spymemcached для реализации моей логики кэширования. Как-то мне нужно использовать CAS для одновременного изменения некоторого содержимого в кеше.не понимаю пример кода spymemcached

Я видел, что владелец уже показал очень хороший пример того, как использовать CASMutation здесь: http://code.google.com/p/spymemcached/wiki/Examples#Using_CAS

Но у меня есть один вопрос об этой части кода:

// Not strictly necessary if you specify the storage as 
// LinkedList (our initial value isn't), but I like to keep 
// things functional anyway, so I'm going to copy this list 
// first. 
LinkedList<Item> ll = new LinkedList<Item>(current); 

Даже если я внимательно прочитайте комментарии, я до сих пор не понимаю, что именно он пытается сделать здесь. Что делать, если мы просто используем «ток» без копирования на «ll»? Каковы потенциальные проблемы?

[UPDATE]

Я следую пример кода и реализован метод, как это, будет работать?

public <T> Set<T> addItemToSet(String key, int expire, final T newItem) throws Exception  { 

    // This is how we modify a list when we find one in the cache. 
    CASMutation<Set<T>> mutation = new CASMutation<Set<T>>() { 

     // This is only invoked when a value actually exists. 
     public Set<T> getNewValue(Set<T> current) { 
      current.add(newItem); 
      return current; 
     } 

    }; 

    HashSet<T> initialValue= new HashSet<T>(); 
    initialValue.add(newItem); 

    CASMutator<Set<T>> mutator = new CASMutator<Set<T>>(memClient, getTranscoder()); 

    return mutator.cas(key, initialValue, expire, mutation); 
} 

Я в основном обеспокоен тем, является ли он потокобезопасным.

ответ

2

не использовав библиотеку, я считаю, , что произойдет, если вы не копировали, в данном случае, является то, что вы получите исключение, как вы пытаетесь изменить Collections.singletonList(), который неизменен. Некоторые реализации List просто не могут быть изменены, и, как правило, это плохая идея предположить, что вы можете. (Было бы замечательно, если бы Java разделила концепцию List как проиндексированную читаемую последовательность, а также на субинтерфейс MutableList со всеми операциями add и set, но хорошо).

В более широком смысле я даже не уверен, что это «не обязательно». Что здесь происходит, так это то, что вам предоставляется существующий список элементов, и им предлагается вернуть новое значение, которое будет использоваться, если условия CAS сохраняются. Если вы измените список на месте и затем вернетесь current, проблема в том, что вы потеряли условность - текущий список имеет, который был изменен (вами), даже если логика CAS означает, что ваше предлагаемое новое значение будет отклонено.

Теперь, возможно, это практически не имеет значения на практике, потому что логика библиотеки означает, что значение, фактически сохраненное в кеше, не обновляется; и изменение состояния переходного процесса также не является проблемой, потому что после достаточного количества попыток ваше обновление будет успешным.

Но я согласен с тем, что нет оснований вообще не использовать функциональный подход - вам дается аргумент ввода для чтения и ожидается, что он вернет список, содержащий ваши изменения. Это намного лучше для ясности, надежности и рассуждений о программе, для создания нового списка с правильными значениями и возврата. Выполнение в противном случае может работать или не работать, но кто хочет написать код, чья семантика зависит от деталей реализации других библиотек, когда у вас есть возможность написать что-то однозначное?

Смежные вопросы