我的程序如下工作:两个期货在一些随机等待时间之后将一个特定金额从一个余额A转移到余额B. 每次重复做10次.所以我尝试停止程序并解决未来,但它不起作用,它抛出NullPointerException,因为我deref它.我做错了什么?
我想要一个最终结果,在程序结束前的最后一行显示balanceA和balanceB.现在它输出结果,但它出现在"转移"和"尝试"内.我需要做什么?
谢谢.
(def balanceA (ref 1000)) (def balanceB (ref 2000)) (def agentCount (agent 1)) ;;transfer function (defn transfer [balanceA balanceB amount futureNum waitingTime] (dosync(alter balanceA - amount)) (Thread/sleep waitingTime) (dosync(alter balanceB + amount)) (do( (println "Trying" futureNum waitingTime) (println "Transfered" futureNum @agentCount) (send-off agentCount inc)))) ;;futureA (dotimes [n 10](def futureA (future (transfer balanceA balanceB 20 1 (rand-int 100))))) ;;futureB (dotimes [n 10](def futureB (future (transfer balanceA balanceB 15 2 (rand-int 40))(prn "result" @balanceB @balanceB)))) ;;print out the result (println "result" @balanceA @balanceB) ;;dereference futures (@futureA) (@futureB
这是我的输出:
user=> (load-file "assignment10.clj") Result: Trying: Trying: 2650 2000 2 Trying: 2 Trying: 2 3 Transfered: 2 1 user=> Trying: 1 28 Transfered: 1 2 Trying: 1 28 Transfered: 1 3 Trying:Trying: 21 2218 Transfered: 2 4 Transfered: 1 4 97 Transfered: 2 6 10 Trying: 2 26 Transfered: 2 7 Transfered: 2 Trying: 8 2Trying:Transfered: 227 2 28 Transfered:7 Transfered: 2 9 2 9 Trying: 2 33 Transfered: 2 12 Trying: 1 49 Trying: 2 39 Transfered:Transfered: 21 1313 Trying: 1 57 Transfered: 1 15 Trying: 1 71 Transfered: 1 16 Trying: 1 76 Transfered: 1 17 Trying: 1 81 Transfered: 1 18 Trying: 1 93 Transfered: 1 19 Trying: 1 98 Transfered: 1 20
Arthur Ulfel.. 6
有几个地方你有一些额外的()
s,其中任何一个都可能导致NullPointerExceptions
(@futureA)
表示首先从ref获取当前值,然后获取该值并将其作为函数调用.
(do( (println "Trying" futureNum waitingTime) (println "Transfered" futureNum @agentCount) (send-off agentCount inc))))
因为它将打印"Trying"作为一个函数调用的结果是一个额外的()
s 组do
,谁的第一个参数是打印"Transfered"的结果,而第二个参数是调用send-off的结果.由于println总是返回,nil
这将导致NPE.似乎这些()
都是无意的.
def
除了顶级表单之外,调用除了顶级表单之外的任何东西都是不寻常的(除非你正在编写宏).在这种情况下,只有futureA和futureB的最后一次出现才有用.可能值得考虑使用for
而不是将所有期货的结果保存在序列中,以便您可以看到它们中的任何一个是否失败,而不是仅仅能够判断最后一个是否失败.
有几个地方你有一些额外的()
s,其中任何一个都可能导致NullPointerExceptions
(@futureA)
表示首先从ref获取当前值,然后获取该值并将其作为函数调用.
(do( (println "Trying" futureNum waitingTime) (println "Transfered" futureNum @agentCount) (send-off agentCount inc))))
因为它将打印"Trying"作为一个函数调用的结果是一个额外的()
s 组do
,谁的第一个参数是打印"Transfered"的结果,而第二个参数是调用send-off的结果.由于println总是返回,nil
这将导致NPE.似乎这些()
都是无意的.
def
除了顶级表单之外,调用除了顶级表单之外的任何东西都是不寻常的(除非你正在编写宏).在这种情况下,只有futureA和futureB的最后一次出现才有用.可能值得考虑使用for
而不是将所有期货的结果保存在序列中,以便您可以看到它们中的任何一个是否失败,而不是仅仅能够判断最后一个是否失败.