2012-05-13 53 views
12

考虑下面的代码:在一个实例中的Java两个同步的方法

public class SynchronizedCounter extends Thread { 
    private int c = 0; 

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

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

    public void run() { 
     for(;;) 
      increment(); 
    } 
} 

static void main(String[] args) { 
    SynchronizedCounter counter = new SynchronizedCounter(); 
    counter.start(); 
    for(;;) 
     counter.decrement(); 
} 

这是否意味着增量()递减()方法将等待对方完成与否?

编辑: 这不等待?

static void main(String[] args) { 
    SynchronizedCounter counter1 = new SynchronizedCounter(); 
    SynchronizedCounter counter2 = new SynchronizedCounter(); 
    counter1.start(); 
    for(;;) 
     counter2.decrement(); 
} 

回答

13

是的,​​关键字是一个速记:

synchronized(this) { 
    //... 
} 

所以,这两种方法都有效地锁定相同的互斥对象。如果你希望它们彼此独立(在这个例子中这是一个坏主意,因为它们都访问相同的值),请参阅Object locking private class members - best practice? (Java)

顺便说一下,你的SynchronizedCounter应该实现Runnable,而不是扩展Thread因为你传递给其他线程的构造函数 - 现在有点混乱。

+0

是啊,你说得对有关扩展线程,只是修复了代码:) – MBZ

6

锁总是整个对象上。如果其中有​​成员被访问。

在你的第一个例子中,有两个线程竞争同一个counter对象,一个你开始明确(它调用increment()方法无限循环),另一个线程是主线程(它调用decrement()无限地)。

在第二个例子中,有两个对象创建counter1counter2。这些将有彼此独立的自己的锁。锁定一个对象不会影响其他线程访问其他对象。两个线程(显式和主线程)获取两个不同对象的锁,因此在中没有争用

1

这是否意味着增量()和递减()方法将等待对方完成或没有?

,这意味着当一个线程在其中时,没有其他线程能够调用increment()和decrement()。是完整的,其他线程无法执行此实例/对象的任何synchronized方法

你可以称之为从一个同步的任何其它synchronized方法无锁相同的实例/对象

相关问题