特定代码段的synchronized语句

时间:2017-07-19 16:17:15

标签: java multithreading

我有来自https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

的以下代码段
public void addName(String name) {
  synchronized(this) {
    lastName = name;
    nameCount++;
  }
  nameList.add(name);
}
  1. 我认为nameList.add(name);也需要处于synchronized块中,因为nameList内容也应该发生在像Collections.synchronizedList(List)这样的关系之前。
  2. 有没有想过这个?

    1. 它还说
    2.   

      如果没有同步语句,则必须单独进行,   unynchronized方法,仅用于调用nameList.add。

      我不明白这句话为什么如果没有synchronized语句,nameList.add应该在一个单独的非同步方法中。

3 个答案:

答案 0 :(得分:4)

通过此示例,他们尝试展示如何部分同步方法,尤其是涉及lastNamenameCount的代码。阅读本文:

  

在此示例中,addName方法需要将更改同步到   lastName和nameCount

因此,可能nameList已经同步,或者对它的更改不需要与lastNamenameCount变量的更改同步。因此,它被排除在同步块之外。

答案 1 :(得分:1)

我理解这个例子试图表明你应该避免从同步块调用其他对象的方法,因为 Starvation 可能会发生,因为其他对象的方法可能需要很长时间才能完成。

保证订单的列表似乎并不重要(可能不是要求?),而lastNamenameCount应该是。

答案 2 :(得分:1)

  

我不明白这句话为什么如果没有synchronized语句,nameList.add应该在一个单独的非同步方法中。

他们只是说,如果语言没有提供synchronized语句,那么同步任何内容的唯一方法就是编写synchronized 方法。他们说这会很尴尬,因为有时你想在同一个方法中混合同步和非同步代码。如果没有synchronized语句这样的东西,那么你必须写下这样的东西:

public void addName(String name) {
  addName_subroutine(name);
  nameList.add(name);
}

private synchronized void addName_subroutine(String name) {
    lastName = name;
    nameCount++;
}

该片段应该是想要混合同步和非同步代码的一个例子,但是它们并没有深入探究为什么你可能想要这样写它的原因。