Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block, unless the variant of deref with timeout is used. See also - realized?.
;; A future's calculation is started here and it runs in another thread user=> (def f (future (Thread/sleep 10000) (println "done") 100)) #'user/f ;;if you wait 10 seconds before dereferencing it you'll see "done" ;; When you dereference it you will block until the result is available. user=> @f done 100 ;; Dereferencing again will return the already calculated value. => @f 100
;; save the example in a script (e.g. test-future.clj) then run it in the console ;; ;; > clojure test-future.clj (println "[Main] calculate the answer to life the universe and everything") ;; Used Thread/sleep to simulate long running process (def what-is-the-answer-to-life (future (println "[Future] started computation") (Thread/sleep 3000) ;; running for 3 seconds (println "[Future] completed computation") 42)) (println "[Main] created future") (Thread/sleep 1000) (println "[Main] do other things while waiting for the answer") (println "[Main] get the answer") (println "[Main] the result" @what-is-the-answer-to-life) (shutdown-agents) ;; You may get something like this ;; ;; [Main] calculate the answer to life, the universe and everything ;; [Future] started computation ;; [Main] created future ;; [Main] do other things while waiting for the answer ;; [Main] get the answer ;; [Future] completed computation ;; [Main] the result 42 ;; Note: If you leave out the call to (shutdown-agents), the program ;; will on most (all?) OS/JVM combinations "hang" for 1 minute before ;; the process exits. It is waiting for a thread created by the ;; future call to be shut down. shutdown-agents will shut them down ;; immediately, or (System/exit <exit-status>) will exit immediately ;; without waiting for them to shut down. ;; This wait occurs even if you use futures indirectly through some other Clojure ;; functions that use them internally, such as pmap or clojure.java.shell/sh ;; http://dev.clojure.org/jira/browse/CLJ-124 is a ticket opened against Clojure, ;; as this 1-minute wait is not considered desirable behavior.
;; Futures will not raise their exceptions... => (def my-future (future (/ 1 0)) ;; ...until dereferenced! => @my-future ArithmeticException Divide by zero clojure.lang.Numbers.divide
;; Given two URLs, create two futures to slurp their HTML, and return ;; the page that returns first. ;; This works because promises can only be delivered once. (let [p (promise)] (let [angieslist "https://angieslist.com" homeadvisor "https://homeadvisor.com"] (doseq [url [angieslist homeadvisor]] (future (let [response (slurp url)] (deliver p response))))) @p)
;; You may want to do some cleanup whenever you cancel your `future` ;; InterruptedException is the catch! ;; lets say we want to feed our doge, but only a limited time... (defn connect! [conn] (println (reset! conn "[doge] very yum"))) (defn response [conn] (println (reset! conn "[doge] so full"))) (defn clean [conn] (println (reset! conn "[doge] so hungry"))) (let [feed-time (rand-int 2000) connection (atom "[doge] such ready") doge-ops (future (try (println @connection) (connect! connection) (Thread/sleep 1000) (response connection) (catch InterruptedException ie (clean connection)) (finally (println "[doge] wow"))))] (printf "[Main] granting many feeding time: %dms\n" feed-time) (if (= :too-late (deref doge-ops feed-time :too-late)) (do (println "[Main] stop!") (future-cancel doge-ops)) @doge-ops)) ;; if he's lucky: [Main] granting many feeding time: 1582ms [doge] such ready [doge] very yum [doge] so full [doge] wow => nil ;; if he's unlucky: [Main] granting many feeding time: 569ms [doge] such ready [doge] very yum [Main] stop! => true [doge] so hungry [doge] wow
;; Notice that future takes a body of expressions. That means it is possible ;; to add a callback for an async computation in the future definition itself. ;; There are two cases: ;; 1. If the callback does not need to take the result of the computation ;; as input, just do this: (future (computation) (callback)) ;; 2. If the callback needs to take the result, do this: (future (callback (computation)))
Initiates a shutdown of the thread pools that back the agent system. Running actions will complete...
Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to...
Returns true if a value has been produced for a promise, delay, future or lazy sequence.
Takes a body of expressions and yields a Delay object that will invoke the body only the first tim...
Takes a function of no args and yields a future object that will invoke the function in another th...
Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in...
future