Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it wrong to use a Java future for an infinite operation?

I need to implement an infinite operation in a Clojure program. I hope the syntax is reasonably clear for Java programmers too:

(defn- my-operation
    (future
        (while @continue
            (do things)
            (Thread/sleep polling-time)))

That gives me exactly what I want, the operation in a different thread so it does not block the main one, and also a pretty clear and straightforward syntax without having to deal with native Java functions which would force me to use the dot special form.

But the definition of a Java future is a "representation of the result of an asynchronous computation" and in this case, well, I'm not really doing anything with the result.

  • Is it wrong to use them this way?.
  • Is there any technical difference that should worry me compared to starting my own Thread?.
  • Is this semantically wrong?.
like image 208
Jacob Avatar asked Jan 29 '23 16:01

Jacob


1 Answers

This will tie up a thread in the thread pool that Clojure manages, and uses for such things. The intended use of that thread pool is for short running operations, so it's kind-of a misuse. Also, the intention behind a future is to calculate a value once so it can be dereferenced multiple times, so that's kinds-of a misuse too.

There are lots of other options for long running tasks, including using Java's Executor framework, core-async or starting your own thread.

(defonce background-thread (doto (Thread. (fn []
                                            (while @continue
                                              (do things)
                                              (Thread/sleep polling-time))))
                             (.setDaemon true)
                             (.start)))

As others have mentioned, it might be worth thinking about unhandled exceptions. Stuart Sierra's blog post is a great place to start.

The docstring for future says that it returns something you can call deref on. It is a reference type in the same way that delay or atom is, with it's own semantics of how it get's a value and while it's true you could just create a future and let it run forever, if you see a future in some code, it implies that you care about the value it produces.

(clojure.repl/doc future)
-------------------------
clojure.core/future
([& body])
Macro
  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?.
like image 89
l0st3d Avatar answered Feb 06 '23 14:02

l0st3d