Відповіді:
Я настійно рекомендую "Радість Клуджура" або "програмування Clojure" для реальної відповіді на це питання, я можу відтворити короткий фрагмент мотивації для кожного:
почніть з перегляду цього відео з поняття ідентичності та / або вивчення тут .
Координований доступ використовується тоді, коли два особи повинні змінити разом, класичний приклад - переміщення грошей з одного банківського рахунку на інший, його потрібно або повністю перемістити, або зовсім не.
Некоординований доступ використовується тоді, коли потрібно оновити лише одну особу, це дуже поширений випадок.
Синхронний доступ використовується тоді, коли очікується, що дзвінок зачекає, поки всі посвідчення не будуть встановлені перед продовженням.
Асинхронний доступ - це "вогонь і забудь" і нехай Ідентичність в свій час досягне свого нового стану.
ensure
функції: clojure.github.io/clojure/clojure.core-api.html#clojure.core/…, щоб зробити це явним і більш ефективним.
Посилання є для стану, який потрібно синхронізувати між потоками. Якщо вам потрібно відслідковувати купу різних речей, і вам іноді доведеться робити операції, які записують кілька речей одночасно, використовуйте реф. Кожен раз, коли у вас є кілька різних станів, використання refs не є поганою ідеєю.
Атоми призначені для незалежного стану, який потрібно синхронізувати між потоками. Якщо вам ніколи не потрібно буде одночасно змінювати стан атома і нічого іншого, використання at atom є безпечним (зокрема, якщо у всій програмі є лише один фрагмент стану, ви можете помістити його в атом) . Як нетривіальний приклад, якщо ви намагаєтеся кешувати повернені значення функції (тобто запам'ятовувати її), використання атома, ймовірно, безпечно - стан невидимий для всіх поза функцією, тому вам не потрібно хвилюватися про зміну стану всередині функції, що щось псує.
Основна точка агента полягає в тому, що вони працюють в іншій нитці. Ви можете отримати значення агента і сказати йому застосувати функцію до його значення, але ви не знаєте, коли функція запуститься або яке значення буде застосовано до цієї функції.
Vars - це коли потрібно зберігати щось за ниткою. Якщо у вас є багатопотокова програма, і кожен потік потребує свого приватного стану, поставте цей стан у вар.
Що стосується прикладів у реальному світі, якщо ви надаєте приклад того, що ви намагаєтеся зробити, ми можемо сказати вам, що використовувати.
Коли я вперше читав про ці типи, я також намагався зрозуміти, де я можу або повинен використати кожен з них, тож ось моя проста англійська відповідь:
Використовуйте var, коли дані не зміняться. Це відбувається щоразу, коли ви використовуєте def
або більшість функцій, які починаються з def
подібних defn
.
Використовуйте атом, коли у вас є один елемент, який змінюється. Прикладом може бути лічильник або вектор, до якого потрібно додати елементи.
Використовуйте посилання, коли у вас є дві або більше речей, які повинні змінюватися одночасно. Подумайте "транзакції бази даних", якщо ви знайомі. Канонічним прикладом цього є переказ грошей з одного рахунку на інший. Кожен обліковий запис може бути збережений у списку, щоб зміни могли бути атомними.
Використовуйте агент, коли ви хочете, щоб щось змінилося, але вам все одно, коли. Це може бути довге обчислення або щось записування у файл або сокет. Зауважте, що з останнім слід використовувати send-off
.
Примітка: Я ціную, що для кожного з них є набагато більше, але, сподіваємось, це має дати тобі вихідну точку.
Я написав статтю з підсумком різниці між ними і допомагаю вибрати, коли використовувати який.
Поділитися станом - при використанні vars, atom, agent та refs?
Я сподіваюся, що це допоможе людям, які шукають відповіді на цю тему.
Деякі ярлики зі статті після пропозиції @tunaci:
Варс
Vars є глобальними для кожної нитки.
Не змінюйте vars після створення. Це технічно можливо, але це погана ідея з багатьох причин.
Атоми
Поділитися доступом до змінного стану для всіх потоків. Зміна відбувається синхронно. Повторіть спробу, коли інший потік змінить стан під час виконання.
Не використовуйте неідентичні функції та функції з тривалим виконанням
Агенти
Поділитися доступом до змінного стану для всіх потоків. Зміна відбувається асинхронно.
Реф
Refs працює аналогічно транзакціям із базами даних. Запис і читання захищають у досинк. Ви можете оперувати багатьма безпечними транзакціями.
І блок-схема, коли використовувати яку:
Перегляньте зображення на веб-сайті, оскільки деякі оновлення завжди можливі.
Це складна і довга тема, щоб дати повну відповідь без копії та минулої статті, тому, будь ласка, пробачте, я перенаправляю вас на веб-сайт :)
атоми, коефіцієнти безпеки та агенти - деяке освітлення тут http://blog.jayfields.com/2011/04/clojure-state-management.html
state-a
, але посилаюся наstate-b
це, мені все-таки потрібнаref
правильна? Отже, це не зміна кількох речей, а посилання на кілька речей, змінюючи будь-яку з них?