2013-10-03 15 views
0

我想知道這個表達式是否正確,如果是這樣的話:我在字段狀態上寫了一個鎖,並且比我更改它。如果不是,我想知道參數的含義是什麼,因爲我總是看到這個關於參數塊同步的含義的說明

public class Example { 
    private int status; 
    public Example(int status){ 
     this.status = status; 
    } 
    public void setStatus(int newStatus){ 
     synchronized(this.status){ 
      this.status = newStatus; 
     } 
    } 
} 

回答

4

有幾件事情錯了,此代碼:

  1. 你不能在一個原始synchronize

    你可以將其更改爲Integer見下文。

  2. 同步非最終目標上是不是一個好主意。

    你可以把它final

  3. 更改領域中,上會在一些非常模糊的方式來打破被​​一段時間。現在它是final它不會被允許。

    可能更適合在另一個領域進行同步。

  4. 你也應該提供完整get方法。

所有這些問題的固定的代碼看起來是這樣的:

public class Example { 
    private final Object statusLock = new Object(); 
    private Integer status; 

    public Example(Integer status) { 
    this.status = status; 
    } 

    public void setStatus(Integer newStatus) { 
    synchronized (statusLock) { 
     status = newStatus; 
    } 
    } 


    public Integer getStatus() { 
    return status; 
    } 
} 

現在 - 與此代碼 - 在回答你的問題是。這裏發生的是,你從鎖定任何其他線程通過設置方法所有訪問status當你改變它的價值。

請注意,我不會在get方法中同步。如果我這樣做了,那麼上面的陳述就會改變。

+0

我在示例中使用了一個基元,但在我的項目中我使用了一個對象 – Oxenarf

+0

@Oxenarf - 您仍然無法更改您在setter中鎖定的對象。 – OldCurmudgeon

0

我看到你正在同步領域this.status這是一個int。 在基本類型上進行同步是不可能的。只在對象或類上。

爲什麼不考慮使用AtomicInteger

public class Example 
{ 
    private AtomicInteger status; 

    public Example(int status) 
    { 
    this.status = new AtomicInteger(status); 
    } 

    public void setStatus(int newStatus) 
    { 
    this.status.getAndSet(newStatus); 
    } 
} 
+0

正確,但應該是一條評論,因爲它不回答OP的問題。 –

0

不,你的表達並不意味着你在想什麼。同步塊的參數是在運行同步塊並在結束時釋放之前獲取的鎖。在Java中,從Object繼承的所有內容都可以用作鎖(因此,不能將int用作鎖)。

鎖只能由一個線程在一個時間被保持,但相同的同步塊中的代碼可以在多個線程內同時運行,如果不同的對象被給予作爲參數。另一方面,如果兩個不同的同步塊被賦予相同的鎖作爲參數,那麼兩個線程將不能運行來自不同同步塊的不同代碼。

人們經常使用this作爲鎖,但使用專門用作鎖的對象也很常見,這是OldCurmudgeon在她的回答中所做的。