多线程时,分享呼叫和引用呼叫是否有所不同?

时间:2012-12-16 06:33:33

标签: java evaluation-strategy

如果使用Call-by-Reference调用函数,则对函数内部变量所做的任何更改都会立即对调用者产生影响。对于Call-by-Sharing,它会在函数结束时受到影响。

问题1: Java是否使用Call-by-Sharing代替Call-by-Reference

问题2:我认为Call-by-Sharing与多线程的Call-by-Reference 不同。它的创建只是为了减少在某些其他线程中使用时值的并发重写;提供一致性。我是对的吗?

3 个答案:

答案 0 :(得分:8)

我建议您不要使用“通过共享呼叫”术语。正如this Wikipedia article所述:

  

“但是,”通过共享调用“这个术语并不常用;术语在不同来源之间是不一致的。例如,在Java社区中,他们说Java是按值传递的,而在Ruby社区中,他们说Ruby是传递引用[引用需要],即使这两种语言表现出相同的语义。分享共享意味着语言中的值基于对象而不是基本类型。 “

  

“虽然这个术语在Python社区中有广泛的用法,但其他语言(例如Java和Visual Basic)中的相同语义通常被描述为按值调用,其中值隐含为对其的引用。对象“。

底线是Java使用“通过共享调用”......但他们并没有这样称呼它,如果你想让Java人员了解你,你可能也不应该这样做。


  

我认为Call-by-Sharing仅在多线程时与Call-by-Reference不同。它的创建只是为了减少在某些其他线程中使用时值的并发重写;提供一致性。我是对的吗?

不,你不对。

“通过共享调用”实际上意味着在值是对象引用的情况下“按值调用”。真正的“引用调用”意味着您(实际上)传递变量的地址,并且被调用的方法可以更新变量。

答案 1 :(得分:3)

众所周知,Java是按值传递(使用更常见的白话),但是由于将对象引用传递给方法允许该方法修改对象,因此产生了很多混淆。调用者的范围(即,他们“共享”对象)。因此,有些人错误地认为Java是非原语的传递参考。据我了解,说“分享呼叫”只是说清楚我们传递的值是对象的引用,而不是对象本身。

相比之下,像R这样的语言是按值传递的,但是将像矢量这样的非基元作为深层副本(技术上是我收集时的写入时复制)传递,这样在方法范围内对对象进行了更改不要修改调用者范围内的向量。

要具体回答你的两个问题,是的,Java是“分享呼叫”,因为我从你链接的维基百科文章中了解它。但是,我不同意按照您描述的方式分享呼叫和呼叫引用不同。一个区别是你不能写一个方法来通过call-by-sharing交换两个变量。

答案 2 :(得分:0)

在对象的名称是对内存中对象的引用的语言中,当一个对象传递一个对象(对该对象的引用)时,通过call-by-shared复制引用,并且实际和形式参数都将引用同一个对象。这与按值调用或按引用调用有何不同......

因此,对于使用该术语的少数人(即Clu程序员),call-by-sharing与call-by-values不同,因为尽管我们将实际参数复制到形式参数中,但它们都是引用;如果我们修改形式参数引用的对象,程序将能够在子例程返回后通过实际参数查看这些更改。

另请注意,在调用期间,可以更改对象的值,这使得它类似于引用调用,但它与引用调用不同,因为对对象的引用被复制,因此对象的身份无法更改。因此,即使在" swap"之后,原始引用变量仍然会引用同一个对象。使用call-by-sharing的例程。