2014-10-31 118 views
1

我有幾個關於java中同步的問題。同步和java中的同步塊

public class A { 

    private int i; 

    public A (int t) { i = t; } 

    public synchronized void increment() { 
     i++; 
    } 

    public synchronized void decrement() { 
     i--; 
    } 
} 

假設我有如上述實施的類和創建類型A的一個對象(p)的

我知道有可能只有一個線程執行p.increment(),但可能的是另一個線程同時執行p.decrement()?

感謝〜

+0

如果對兩種方法使用同步,則只能同時調用一種方法。 – yushulx 2014-10-31 01:19:00

+0

可能的重複[在Java中同步兩個方法](http://stackoverflow.com/questions/24341447/synchronizing-two-methods-in-java) – 2014-10-31 04:27:42

回答

2

​​不保護方法。​​不保護對象。​​做一件事,只有一件事。

的方式你寫你的增量方法其實寫這只是一個速記方式:

public void increment() { 
    synchronized(this) { 
     i++; 
    } 
} 

表達它說清楚,​​上this這種操作方式更長。

因此,​​所做的一件事是:JVM不會允許兩個線程同時在同一個對象上同步。

如果您有一個對象p的類型A,那麼答案是「否」。 JVM不允許一個線程同時執行增量,而另一個線程執行遞減,因爲兩個線程都試圖在同一個對象上同步,p。另一方面,如果你有一個對象p和另一個對象q,兩個類型都是A,那麼一個線程可以在p.increment()調用中,而另一個線程在q.decrement()調用中。這是因爲每個線程將在不同的對象上同步,並且允許


P.S:​​實際上做,涉及到所謂的「發生之前」的概念,Java的一兩件事。在深入研究多線程編程之前,您應該瞭解這些(Google是您的朋友)。

0

實際上由於值被包裹成​​方法中,內容也被同步的,因此沒有,它不會由另一個線程執行

請注意,它可以是由另一個線程調用。個人而言,如果僅僅是遞減/遞增的問題,我不會打擾同步並且會簡單地使用Atomic values

See documentation

+0

謝謝〜是的,我知道在這種情況下最好使用AtomicInteger,但試圖瞭解同步如何在java中工作。 – Yoope 2014-10-31 05:32:50

+0

「執行」與「被調用」有什麼不同? – 2015-02-03 14:24:36

+0

@jameslarge對該方法的調用將完成,但只有在允許的情況下才會執行。 – 2015-02-03 14:38:51

2

號使用​​爲方法改性劑是等同於synchronized(this)包裹方法。

1

編號同步將不允許多個線程進入對象實例的方法。注意如果你有一個p1和一個p2的類A,你可以讓p1.increment()同時運行p2.decrement()(等)正在運行。