Futures and blocking IO

The choice of using ForkJoinPool for imminent is deliberate. The ForkJoinPool—added on Java 7—is extremely smart. When created, you give it a desired level of parallelism, which defaults to the number of available processors.

ForkJoinPool then attempts to honor the desired parallelism by dynamically shrinking and expanding the pool as required. When a task is submitted to this pool, it doesn't necessarily create a new thread if it doesn't have to. This allows the pool to serve an extremely large number of tasks with a much smaller number of actual threads.

However, it cannot guarantee such optimizations in the face of blocking IO, as it can't know whether the thread is blocking waiting for an external resource. Nevertheless, ForkJoinPool provides a mechanism by which threads can notify the pool when they might block.

Imminent takes advantage of this mechanism by implementing the ManagedBlocker (see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinPool.ManagedBlocker.html) interface—and provides another way to create futures, as demonstrated here:

  (-> (immi/blocking-future 
       (Thread/sleep 100)
       10)
      (immi/await))
  ;; #<Future@4c8ac77a: #<Success@45525276: 10>>

  (-> (immi/blocking-future-call
       (fn []
         (Thread/sleep 100)
         10))
      (immi/await))
  ;; #<Future@37162438: #<Success@5a13697f: 10>>

The blocking-future and blocking-future-call have the same semantics as their counterparts, future and future-call, but should be used when the task to be performed is of a blocking nature (that is, not CPU-bound). This allows the ForkJoinPool to better utilize its resources, making it a powerful and flexible solution.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.196.146