2013-05-14 83 views
4

我有这样的方法:两个实例(同步某个对象)平行

public void processChildNodes(Node result, Node source) { 
    synchronized (source) { 
     NodeList nodes = source.getChildNodes(); 
     for (int i = 0; i < nodes.getLength(); i++) { 
      processNode(result, nodes.item(i)); 
     } 
    } 
    } 

现在,让我们说,我想打电话给processChildNodes与类的两个不同的实例中,这方法是相同的来源(方法的第二个参数),是否有可能这两个执行可以并行?

+1

答案是,不。 – Mordechai 2013-05-14 05:43:01

+0

为什么这与单个对象上的同步有什么不同?由于'source'在两次调用中都指向同一个对象,因此它将与在单个对象上进行同步的行为相同。为何混淆? – brainOverflow 2013-05-14 06:22:43

回答

2

不,该方法将被调用,但同步块内的内容不会并行执行。这是因为你已经提到你正在使用相同的源对象。由于在对象上获取锁定,所以同步将正常工作。

0

Java是通过值,意思是Node传递实际上是一个副本。系统为两个独立的方法调用创建两个单独的副本,这意味着这两个副本将并行执行。请注意,这也意味着您的同步块可能无效。小心数据竞赛。

编辑

我做了一点研究,发现this page描述参数是如何工作的。鉴于这些新的信息,我认为我的答案是无效的,但我仍然不能100%确定。

+0

线程不锁定参考!?! – Mordechai 2013-05-14 05:46:45

+2

这不完全正确。 Java会传递一个指向Node的副本。所以Node的价值是共享的,而不是副本。因此,您将在同一个对象上进行同步。 – 2013-05-14 05:48:13

+0

布拉沃,你有勇气承认错误.. [至少只要你保持匿名...] – Mordechai 2013-05-14 05:59:12

2

您正尝试进行对象锁定。如果你传递了相同的对象,那么你的处理将被同步,这意味着一个线程将执行同步块内的代码,另一个线程将等待它。但是如果你传递两个不同的对象,那么它们将使用两个不同的锁,这意味着它们不依赖于彼此来获取锁。所以他们都会并行执行。

正如您编写代码并尝试使用源对象来同步执行一样。因此,请确保您的两个线程都使用相同的源对象来获得所需的结果。

+0

嗯我同意你,但基于行为我看到它似乎同步块正在执行并行调用方法使用两个不同的类对象具有相同的源对象。 – user999491 2013-05-14 06:01:56

+0

您可以共享创建节点对象的代码以及调用processChildNodes的代码。 – 2013-05-14 06:06:17

+0

是的,我确定我会分享一段时间 – user999491 2013-05-14 06:15:50

1

因为您使用源对象来同步同步应该正常工作。如果两个实例中使用的对象不同,则两个执行可能并行发生。