2012-07-31 82 views
0

我下面的類Java併發混亂

class A{ 

private int id =0; 
    public void setMessageId(Message m) { 
     synchronized(m) { 
     m.setId(id++); 
     } 
    } 
} 

兩個線程與A級與消息的不同實例相同的實例可以進入synchronized塊在同一時間,同一ID設置爲消息的不同實例?

回答

2

是的。由於塊在消息上是同步的,所以使用兩個不同消息實例的兩個線程可以同時進入同步塊,並且兩者都獲得相同的ID。

使方法同步,一切都會好的。或者使用AtomicInteger。

3

是的。您需要在包含id字段(本例中爲'A')或某個常見對象的對象上進行同步。

+0

我可以只是同步setMethodId(...)方法,因爲id只在該區域中被修改。 – darkapple 2012-07-31 07:29:07

+1

@darkapple,是的。 – Nim 2012-07-31 07:29:33

0

如果您只在m上進行同步,則兩個對象將能夠修改A的同一個實例。您需要在存儲值id的對象上進行同步。

0

當然,因爲你在不同的對象上同步。

如果您爲此目的而需要的所有內容,那麼使用java.util.concurrent AtomicInteger更好。

例如是這樣的:

private AtomicInteger counter; 

public int getNextUniqueIndex() { 
    return counter.getAndIncrement(); 
} 
0

明顯,這是因爲鎖定時Message m和如果兩個線程具有Message不同實例那麼他們可以..

0

1.作爲同步鎖定時消息的實例,然後兩個紗線具有不同的消息對象可以肯定在同一時間訪問該塊。

2.即使如果它們被設置相同的實例變量,其類似於個人副本是每個對象一個。

3.螺紋改變可變id一個對象的不會影響其他對象的id。

0

是:

爲米對象獲得的鎖定對象其是爲每個線程所以是他們可以的2個不同的對象。你需要獲得一個鎖,在你的情況下,這兩個鎖共享這2個類。

0

是的,因爲它們都具有鎖不同的對象。沒有在所有的自制同步

一種選擇是使用AtomicInteger:由一個並返回更新後的值

class A{ 
    private final AtomicInteger id = new AtomicInteger(); 

    public void setMessageId(Message m) { 
     m.setId(id.incrementAndGet());  
    } 
} 

方法incrementAndGet incerements值。