Внимательно посмотрите на эти две строки:
(.start (Thread. (rover-thread mr1-id mr1-movs update-work-block)))
(.start (Thread. (rover-thread mr2-id mr2-movs update-work-block))))))
Этот код сначала оценивает (rover-thread mr1-id mr1-movs update-work-block)
и передает результат этого конструктору Thread
, а это не то, что вам нужно.
Вот простая функция, иллюстрирующая принцип. Это не работает, потому что (f ...)
вычисляется до того, как его результат передается конструктору Thread
:
(defn run-thread-thing-wrong []
(let [f (fn [n s]
(doseq [i (range n)]
(prn s i)
(Thread/sleep (rand 1000))))]
(.start (Thread. (f 10 "A")))
(.start (Thread. (f 10 "B"))))
nil)
Вот версия, которая работает. функция передается конструктору Thread
вместо:
(defn run-thread-thing []
(let [f (fn [n s]
(doseq [i (range n)]
(prn s i)
(Thread/sleep (rand 1000))))]
(.start (Thread. (fn [] (f 10 "A"))))
(.start (Thread. (fn [] (f 10 "B")))))
nil)
Примечание: вместо (fn [] ....)
вы можете использовать краткую форму #(....)
для анонимных функций.
Вот еще одна версия, которая делает то же самое, но с future
вместо создания потоков вручную:
(defn run-thread-thing []
(let [f (fn [n s]
(doseq [i (range n)]
(prn s i)
(Thread/sleep (rand 1000))))]
(future (f 10 "A"))
(future (f 10 "B")))
nil)
Обратите внимание, что в этом случае вы передаете форму future
вместо функции.