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 <[email protected]> wrote:
> On Dec 26, 11:42 pm, Alex Osborne <[email protected]> wrote:
>> justinhj <[email protected]> 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 [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en