Попробуйте семя-fu плагин, который является вполне простым плагином, который позволяет Вам отбирать данные (и изменение, которые отбирают данные в будущем), также позволит Вам отобрать среду определенные данные и данные для всех сред.
Clojure fn
являются Runnable
, поэтому их обычно используют точно так, как вы разместили, да.
user=> (dotimes [i 10] (.start (Thread. (fn [] (println i)))))
0
1
2
4
5
3
6
7
8
9
nil
Другой вариант - использовать агентов , и в этом случае вы должны отправить
или отправку
, и он будет использовать поток из пула.
user=> (def a (agent 0))
#'user/a
user=> (dotimes [_ 10] (send a inc))
nil
;; ...later...
user=> @a
10
Еще один вариант - pcalls
и pmap
. Еще есть будущее
. Все они описаны в Clojure API .
Программирование на Clojure не решает этот вопрос до тех пор, пока не появится страница 167: «Использование агентов для асинхронных обновлений».
Перед тем, как начать темам, обратите внимание, что Clojure будет работать в многозадачном режиме самостоятельно, если у вас будет половина шанса. Я писал программы, совершенно игнорирующие параллелизм, и обнаружил, что при правильных условиях они занимают более одного процессора. Я знаю это' Это не очень строгое определение: я еще не исследовал это подробно.
Но для тех случаев, когда вам действительно нужно явное отдельное действие, одним из ответов Clojure, по-видимому, является агент.
(agent initial- state)
создаст его. Это не похоже на Java Thread с точки зрения того, что это блок кода, ожидающий выполнения. Вместо этого это занятие, ожидающее, чтобы ему дали работу. Это делается с помощью
(send agent update-fn & args)
В примере
(def counter (agent 0))
counter
- ваше имя и дескриптор для агента; состояние агента - это число 0.
Установив это, вы можете отправить работу агенту:
(send counter inc)
скажет ему применить данную функцию к своему состоянию.
Позже вы можете извлечь состояние из агента, разыменовав его:
@counter
даст вам текущее значение числа, которое начинается с 0.
Функция await
позволит вам выполнить что-то вроде соединения
на активность агента, если она будет долгой:
(await & agent)
будет ждать, пока все не закончатся; есть еще одна версия, для которой требуется тайм-аут.
Да, способ запуска Java-потока в Clojure примерно такой же, как у вас там.
Однако реальный вопрос: зачем вам это нужно. сделать это? Clojure имеет намного конструкции параллелизма лучше, чем потоки.
Если вы посмотрите на пример канонического параллелизма в Clojure, моделирование муравьиной колонии Ричарда Хикки , вы увидите, что он использует ровно 0 потоков. . Единственная ссылка на java.lang.Thread
во всем исходном коде - это три вызова Thread.sleep
, единственная цель которых - замедлить моделирование, чтобы вы могли фактически см. , что происходит в пользовательском интерфейсе.
Вся логика выполняется в агентах: один агент для каждого муравья, один агент для анимации и один агент для испарения феромона. Игровое поле - это транзакционная ссылка. Ни нити, ни замка не видно.
Использование future-объекта обычно является самым простым adhoc-доступом к потокам. Полностью зависит от того, что вы хотите сделать :)