https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel%28boolean%29
may explain why future-cancelled? is returning true..

After this method returns, subsequent calls to isDone() 
<https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#isDone%28%29>
 
will always return true. Subsequent calls to isCancelled() 
<https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#isCancelled%28%29>
 
will always return true if this method returned true.

Thread will not stop.. but future is now cancelled.
Future represents some value in future and it should have one value after 
it is done.
The values that future is `still` calculating will now be not useful since 
its status is cancelled.
A cancelled future can also have some value but it's status means that it 
is not usable.

** It is true that i am trying to put logic after seeing the results. :(
Do correct me if something is wrong.


On Saturday, 30 April 2016 05:50:38 UTC+5:30, Tom Bodenheimer wrote:
>
> Hi, this actually boils down to a strong case of read the manual and one 
> surprising effect.
>
> The executive summary: From the Java SE 8 docs description for 
> Thread/sleep:
>
> Throws:IllegalArgumentException 
> <https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalArgumentException.html>
>  - 
> if the value of millis is negativeInterruptedException 
> <https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html>
>  - 
> if any thread has interrupted the current thread. The *interrupted status* of 
> the current thread is cleared when this exception is thrown.
>
> The key to my misunderstanding is right there is the InterruptedException 
> doc - the interrupted status is cleared by Thread/sleep.
>
> The remaining surprise is that the future-cancel call actually returns 
> true for all the cases (which is different from what I originally wrote). 
>  Check out the below examples.
>
> Example 1 - just a normal future with no try/catch
> user> (defn test-interrupt-status-1 [init-v]
>   (let [n (atom init-v)]
>     [n
>      (future (while (not (Thread/interrupted))
>                (swap! n inc)))]))
> #'user/test-interrupt-status-1
> user> (def test-1 (test-interrupt-status-1 10))
> #'user/test-1
> user> (future-cancel (test-1 1))
> true
> user> (future-cancelled? (test-1 1))
> true
> user> @(test-1 0)
> 43202690
> user> @(test-1 0)
> 43202690
>
> Example 2 - a future that contains a try/catch but doesn't have any sleep 
> included
> Notice that future-cancel works fine even with the try/catch - the atom 
> isn't updated
> after the future-cancel is called on the future.
> user> (defn test-interrupt-status-2 [init-v]
>   (let [n (atom init-v)]
>     [n
>      (future (while (not (Thread/interrupted))
>                (try
>                  (swap! n inc)
>                  (catch Exception e (println (str "Exception:\t" e 
> "\nisInterrupted:\t" (.isInterrupted (Thread/currentThread))))))))]))
> #'user/test-interrupt-status-2
> user> (def test-2 (test-interrupt-status-2 10))
> #'user/test-2
> user> (future-cancel (test-2 1))
> true
> user> (future-cancelled? (test-2 1))
> true
> user> @(test-2 0)
> 44066815
> user> @(test-2 0)
> 44066815
>
> Example 3 - now we have a future which includes a try/catch AND A 
> Thread/sleep
> Calling future-cancel returns true (!!) and we see that the Thread/sleep
> has cleared the interrupt status of the thread (e.g., the .isInterrupted 
> is false
> for the thread).  What is interesting here is that future-cancelled? 
> returns true
> but the thread is actually still happily running because the interrupt 
> status was 
> reset.  I'm not sure what I think about this - I hate surprises, but the 
> docs are pretty
> clear on what is happening here.  
> user> (defn test-interrupt-status-3 [init-v]
>   (let [n (atom init-v)]
>     [n
>      (future (while (not (Thread/interrupted))
>                (try
>                  (Thread/sleep 10000)
>                  (swap! n inc)
>                  (catch Exception e (println (str "Exception:\t" e 
> "\nisInterrupted:\t" (.isInterrupted (Thread/currentThread))))))))]))
> #'user/test-interrupt-status-3
> user> (def test-3 (test-interrupt-status-3 10))
> #'user/test-3
> user> (future-cancel (test-3 1))
> trueException: java.lang.InterruptedException: sleep interrupted
> isInterrupted: false
> user> (future-cancelled? (test-3 1))
> true
> user> @(test-3 0)
> 12
> user> @(test-3 0)
> 13
> user> (future-cancel (test-3 1))
> false
> user> (future-cancelled? (test-3 1))
> true
>
>
> On Thursday, April 28, 2016 at 11:48:29 AM UTC-4, Tom Bodenheimer wrote:
>>
>> Hi all,
>>
>> I have recently been playing with futures and have stumbled on the 
>> following situation.
>>
>> (defn test-f1 [initial-v]
>>   (let [n (atom initial-v)]
>>     [n
>>      (future (while (not (Thread/interrupted))
>>                (Thread/sleep 5000)
>>                (swap! n inc)
>>                (println @n)))]))
>>
>> (def t1 (test-f1 11))
>>
>> This works as expected.  I see the println outputs, can @(t1 0) and 
>> (future-cancel (t1 1)) returns true.
>>
>> Then I have:
>>
>> (defn test-f2 [initial-v]
>>   (let [n (atom initial-v)]
>>     [n
>>      (future (while (not (Thread/interrupted))
>>                (try
>>                  (Thread/sleep 5000)
>>                  (swap! n inc)
>>                  (println @n)
>>                  (catch Exception e (println "whoops")))))]))
>>
>> (def t2 (test -f2 11))
>>
>> The same except now my while has a (try ... (catch Exception e ...). 
>>  However, now (future-cancel (t2 1)) returns false and the future cannot be 
>> cancelled - I also see the "whoops" at the REPL.  Seeing that "whoops" made 
>> me wonder if the interrupt that would shutdown the thread is raising an 
>> exception that is being caught by my (try .... (catch ...)) block, thus 
>> never interrupting the thread. 
>>
>> I made a change to throw the exception again:
>>
>> (defn test-f3 [initial-v]
>>   (let [n (atom initial-v)]
>>     [n
>>      (future (while (not (Thread/interrupted))
>>                (try
>>                  (Thread/sleep 5000)
>>                  (swap! n inc)
>>                  (println @n)
>>                  (catch Exception e (do (println "whoops") (throw 
>> e))))))])) 
>>
>> and the behavior now matches that of test-f1.
>>
>> I think I'm just not clear on some fundamental aspect of how 
>> future-cancel, try/catch, and the underlying java are actually working here.
>>
>> It seems *very* weird to me that after future-cancel cancels the future, 
>> that the (try . . . (catch . . .)) would ever be invoked in the body of the 
>> while loop.  Yet, clearly the interrupt is being handled in the (try . . . 
>> (catch . . . )).  It also seems *very* weird that even in this case, that 
>> the next time we get back to (while (not (Thread/interrupted)) that 
>> (not(Thread/interrupted)) would be true . . . I guess the exception sets 
>> the interrupt status for the thread.  When exception gets caught in my (try 
>> . . . (catch . . .)), the interrupt status is never set?
>>
>> Thanks for any clarification.
>>  
>>
>>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to