我的程序如下工作:两个期货在一些随机等待时间之后将一个特定金额从一个余额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
Run Code Online (Sandbox Code Playgroud)
这是我的输出:
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
Run Code Online (Sandbox Code Playgroud)
有几个地方你有一些额外的()s,其中任何一个都可能导致NullPointerExceptions
(@futureA)
Run Code Online (Sandbox Code Playgroud)
表示首先从ref获取当前值,然后获取该值并将其作为函数调用.
(do(
(println "Trying" futureNum waitingTime)
(println "Transfered" futureNum @agentCount)
(send-off agentCount inc))))
Run Code Online (Sandbox Code Playgroud)
因为它将打印"Trying"作为一个函数调用的结果是一个额外的()s 组do,谁的第一个参数是打印"Transfered"的结果,而第二个参数是调用send-off的结果.由于println总是返回,nil这将导致NPE.似乎这些()都是无意的.
def除了顶级表单之外,调用除了顶级表单之外的任何东西都是不寻常的(除非你正在编写宏).在这种情况下,只有futureA和futureB的最后一次出现才有用.可能值得考虑使用for而不是将所有期货的结果保存在序列中,以便您可以看到它们中的任何一个是否失败,而不是仅仅能够判断最后一个是否失败.