2016-01-12 57 views
0

我有一個簡單的問題,但無法找到一個正確的答案。想象一下,我們有;在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)不在同步塊中。

+0

問題不明確,你是什麼意思的「塊」?同步塊之外的任何代碼都不會同步 - 如果這就是您的意思。 – alfasin

+0

請澄清「阻塞」的意思是最具體的,因爲我們無法在不知道實際意義的情況下回答您的問題(這不是一個標準的Java術語,我認爲這對您個人而言意味着什麼......)。 –

+0

好的。讓我再嘗試一次。假設線程A在上面調用了這個函數,但是它會等待'this'鎖被線程B釋放,而線程B在其他方法之前有鎖。現在,我想知道在線程A正在等待'this'鎖對象時,執行是否會從B的nameList.add(name)方法中恢復 - 因爲nameList.add(name)不在同步塊中。 – zgulser

回答

1

,我想知道,如果執行將來自B的nameList.add(name)方法恢復,而線程A是在「這」鎖定對象的等待 - 因爲nameList.add(名)是不是在同步塊。

不,執行該方法的線程不能跳過該塊並執行該方法的其餘部分。它會做的是阻塞,直到它可以獲取this上的監視器,然後執行同步塊,然後釋放監視器this,然後將該字符串添加到nameList。

如果併發線程執行此操作,則不能保證哪個線程將首先插入到nameList中。有可能在線程釋放this上的監視器和添加到nameList的時間之間,一個或多個其他線程可能會插入並添加到列表中。

此外,無論nameList實現爲需要成爲線程安全集合,以便併發更改不會導致錯誤,以便跨線程可見更改。例如,如果nameList是一個ArrayList或一個HashSet,那麼這將不安全。

0

在原理上,關鍵字​​做以下兩兩件事:通過synchronized關鍵字把守

  • 代碼不能被一個以上的線程同時執行 ;
  • ..它控制線程之間數據(變量)的可見性;

    在您的示例中,不在​​作用域中的代碼可供所有調用此方法的其他線程訪問;

假設這是超出範圍的操作是寫操作時,你會(一般),希望它是​​減少可能攀升任何異常。

0

synchronized(this)會阻塞if和while另一個線程在此塊內。如果線程離開該塊,則一個等待線程有機會(在其他等待線程中)進入該塊。 namelist.add()在同步範圍之外執行,所以它可以與其他線程並行執行。現在