2014-10-31 121 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()(等)正在运行。