java 中同步块后的代码

Code after synchronized block in java

我有一个简单的问题,但找不到合适的答案。假设我们有;

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }

    nameList.add(name);
} 

同步后的代码呢。堵在这里?我的意思是同步。块用于减少锁定范围,但这里它后面的代码 ( namelist.add(name) ) 将被阻塞,对吗?

假设线程 A 在上面调用了这个函数,但它会等待 'this' 锁被线程 B 释放,线程 B 之前在其他方法上拥有锁。现在,我想知道当线程 A 正在等待 'this' 锁定对象时,执行是否会从 B 的 nameList.add(name) 方法恢复 - 因为 nameList.add(name) 不在同步块中。

原则上,关键字 synchronized 做以下两件事:

  • synchronized关键字保护的代码无法执行 同时由多个线程;

  • ..它控制线程间数据(变量)的可见性;

    在您的示例中,不在 synchronized 范围内的代码可以被调用此方法的所有其他线程访问;

假设超出范围的操作是写操作,您(通常)希望它是 synchronized 以减少任何可能蔓延的异常。

synchronized(this) 将在另一个线程在此块内时阻塞。如果线程离开这个块,一个等待线程有机会(在其他等待线程中)进入这个块。 namelist.add()在synchronized作用域外执行,所以可能与其他线程并行执行。

Now, I wondered if the execution will resume from B's nameList.add(name) method while thread A is waiting on 'this' lock object - since nameList.add(name) is not in the sync block.

不,执行该方法的线程不能跳过该块并执行该方法的剩余部分。它要做的是阻塞,直到它可以获取 this 上的监视器,然后执行同步块,然后释放 this 上的监视器,然后将字符串添加到 nameList。

如果并发线程执行此操作,则无法保证哪些线程将首先插入到 nameList 中。有可能在一个线程在 this 上释放监视器的时间和它添加到 nameList 的时间之间,一个或多个其他线程可能会闯入并添加到列表中。

此外,无论实现什么 nameList 都需要是一个 thread-safe 集合,这样并发更改就不会导致错误,并且更改在线程之间可见。例如,如果 nameList 是 ArrayList 或 HashSet,那么这将不安全。