Your problem is caused by one itty-bitty misplaced parenthesis that is
hard to catch; In your code which creates threads, you do:

 (.start (Thread. (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-int
5000)))))))

#(sleeper-thread %1 %2 %3) is exactly the same as just sleeper-thread,
so this boils down to

(.start (Thread. (sleeper-thread out x (+ 2000 (rand-int 5000)))))))

and now you can see that you are evaulating your sleeper-thread
function before you actually create the thread.

Thread wants Runnable object like a clojure function with no
arguments, so either

 (.start (Thread. #(sleeper-thread out x (+ 2000 (rand-int 5000)))))))

or

 (.start (Thread. (partial sleeper-thread out x (+ 2000 (rand-int 5000)))))))

would work and do what you expect. Here's a modified version of your
code with output:





(ns mailing-list.print-from-threads)

(defn sleeper-thread [out id t]
  "Sleep for time T ms"
  (binding [*out* out]
    (let [start (System/nanoTime)]
      (printf "%d sleeping for time %d\n" id t)
      (Thread/sleep t)
      (printf "%d slept for %d\n" id (int (/ (- (System/nanoTime)
start) 1e6))))))

(defn test-threads-rlm [n out]
  (let [start (System/nanoTime)]
    (dotimes [x n]
      (.start (Thread.
               (partial sleeper-thread  out x (+ 2000 (rand-int
5000))))))
    (println "Total time is:" (int (/ (- (System/nanoTime) start)
1e6)))))


(defn test-threads [n out]
  (let [start (System/nanoTime)]
    (dotimes [x n]
      (.start (Thread.
               (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-int
5000))))))
    (println "Total time is:" (int (/ (- (System/nanoTime) start)
1e6)))))



mailing-list.print-from-threads> (test-threads-rlm 4 *out*)
0 sleeping for time 6783
1 sleeping for time 3716
2 sleeping for time 6890
Total time is: 2
3 sleeping for time 5582
1 slept for 3716
3 slept for 5582
0 slept for 6783
2 slept for 6890
nil
mailing-list.print-from-threads> (test-threads 4 *out*)
0 sleeping for time 5875
0 slept for 5875
1 sleeping for time 3413
1 slept for 3413
2 sleeping for time 3709
2 slept for 3710
3 sleeping for time 5483
3 slept for 5484
Total time is: 18486
nil
mailing-list.print-from-threads>


However, I am vexed at how your original code works at all!

look at this! ---


;;works
(Thread. (#(sleeper-thread %1 %2 %3) *out* 2 (+ 2000 (rand-int
5000))))
(= nil  (#(sleeper-thread %1 %2 %3) *out* 2 (+ 2000 (rand-int 5000))))
;;true


;;doesn't work
(Thread. nil)

;;works
(Thread. ((fn [a b c] (sleeper-thread a b c)) *out* 2 (+ 2000
(rand-int 5000))))

;;works
(Thread. ((fn [])))


How can you  make a Thread with ((fn []))
when (= ((fn [])) nil)  ????


sincerely,

--Robert McIntyre




On Tue, Dec 28, 2010 at 1:45 AM, justinhj <justi...@gmail.com> wrote:
> On Dec 26, 11:42 pm, Alex Osborne <a...@meshy.org> wrote:
>> justinhj <justi...@gmail.com> writes:
>> > I tried passing *out* to my thread function and then binding it to
>> > *out* in the thread, and this works but then makes the threads execute
>> > one at a time, and I'm presuming that is because my use of *out* in
>> > the binding block is blocking for the other threads which use it.
>>
>> That doesn't sound right: binding itself never blocks.  Can you post
>> some example code where you see this behaviour?
>>
>> As I understand it binding conveyance should happen automatically in the
>> upcoming 1.3 release (for futures and agents) but in 1.2 you can use
>> bound-fn, or for better performance use binding explicitly as you
>> suggested.
>>
>>     (future-call (bound-fn [] (println "log...")))
>>
>>     (send some-agent (bound-fn [x] (println "log...") (inc x)))
>
> This is the code I've written so far
>
> (defn sleeper-thread [out id t]
>  "Sleep for time T ms"
>  (binding [*out* out]
>    (printf "%d sleeping for time %d\n" id t)
>    (Thread/sleep t)
>    (printf "%d slept\n" id)))
>
> (defn test-threads [n out]
>  (dotimes [x n]
>    (.start (Thread. (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-
> int 5000)))))))
>
> And the output is
>
> 0 sleeping for time 5480
> 0 slept
> 1 sleeping for time 6739
> 1 slept
> 2 sleeping for time 5444
> 2 slept
> 3 sleeping for time 3087
> 3 slept
> 4 sleeping for time 6753
> 4 slept
> 5 sleeping for time 3489
> 5 slept
> 6 sleeping for time 5864
> 6 slept
> 7 sleeping for time 5523
> 7 slept
> 8 sleeping for time 5659
> 8 slept
> 9 sleeping for time 5052
> 9 slept
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to