2017-01-23 84 views
3

我有一個程序(由於IM在VM中運行的程序在我的情況2),可以自動生成取決於CPU的內核的數量線程2線程在同一時間訪問到同步功能

我有一個名爲CREATETABLE至極函數創建一個表,如果它不存在,問題是,我有多個線程,因此IF statment可能是unusefull,我試圖用同步,但我有同樣的結果

public synchronized void createTable(Utils utils, String tableName, RowSerializable row) { 
    if(!utils.getClient().tableExists(tableName)) { 
     this.table = utils.generateTable(tableName, row); 
     this.fieldsNames = utils.getNamesOfColumns(table); 
    } 
} 

任何想法?

+0

你能提供更多細節嗎?如果在線程之間共享基礎對象的同一實例,則同步方法就足夠了。是你的情況嗎? – davidxxx

+0

您創建了多少個包含此代碼的對象?同步將在* object *級別。如果每個線程創建一個單獨的對象,則不會有同步。 –

+0

你是從兩個不同的對象調用方法嗎?如果在這種情況下是,它將鎖定兩個不同的對象,因此將允許兩個線程訪問此方法代碼。或者採取類級鎖。 (使該方法爲靜態) –

回答

3

您可能會使用多個實例,否則在實例上同步的方法訪問中不會有同步問題。

要解決您的問題,您可以在所有實例共享的靜態字段上進行同步。

在類添加靜態Object,並就同步,它要解決的訪問的併發問題:

public class YourClassThatHasTheProblem { 
    ... 
    private static final Object lock = new Object(); 
    ... 
    public void createTable(Utils utils, String tableName, RowSerializable row) { 
     synchronized (lock) { 
     if(!utils.getClient().tableExists(tableName)) { 
      this.table = utils.generateTable(tableName, row); 
      this.fieldsNames = utils.getNamesOfColumns(table); 
     } 
     } 
    } 
... 
} 

如果不解決您的問題,這意味着該問題不來僅從代碼同步,但因爲您在另一個類或方法中執行了類似的處理,並且與此調用不同步。所以它會產生createTable()調用的副作用。

+0

我也會猜測,我寧願看看他未能分享線程之間的同一個實例。但是,當然,靜態字段很簡單並且很有用。 – AxelH

+1

我認爲它的工作原理!我會繼續測試這個程序。謝謝 –

+0

@AxelH事實上,我明白,但我不確定OP是否真的知道創建競爭條件的資源是如何實例化的。如果解決方案有效,它還可以幫助OP瞭解他使用多個實例,然後研究其代碼以便理解。 – davidxxx

1

有可能是2個線程正在訪問createTable方法,我會試着解釋。

該方法定義了​​,這意味着它同步的對象是this。 所以我的猜測是,在你的程序中,2個線程可能訪問createTable,因爲有兩個不同的對象,每個對象都在同步。

因此,如果2個線程想要創建具有相同名稱的新表 - 這是可能的。

注意:此分析基於您提供的信息,如果您認爲這不太可能,請提供更多信息,我會盡力提供幫助。

+0

This [thread](http:// stackoverflow。com/a/15250419/4391450)可以顯示你的解釋和多一點(靜態) – AxelH

+0

它是同一個實例,所以兩個線程都試圖創建表。第一個創建它,第二個拋出異常 –

+0

@ AxelH - 如果你的意思是我,我刪除了我的評論第二個我發佈它完全是因爲你說的 –