一个实例中的Java两个同步方法

时间:2012-05-13 11:39:05

标签: java multithreading synchronization

考虑以下代码:

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();
}

这是否意味着 increment() decrement()方法将等待彼此完成与否?

修改 这不等了吗?

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

3 个答案:

答案 0 :(得分:13)

是的,synchronized关键字是:

的简写
synchronized(this) {
  //...
}

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

BTW你的SynchronizedCounter应该实现Runnable而不是扩展Thread,因为你将它传递给其他线程的构造函数 - 现在它有点令人困惑。

答案 1 :(得分:6)

锁始终在整个对象上。如果访问synchronized成员中的任何一个。

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

在第二个示例中,创建了两个对象counter1counter2。它们将拥有彼此独立的锁。锁定一个对象不会影响其他线程访问其他对象。两个线程(显式线程和主线程)获取对两个不同对象的锁定,因此存在无争用

答案 2 :(得分:1)

这是否意味着increment()和decrement()方法会等待彼此完成?

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

您可以从同步的方法中调用任何其他同步方法,而无需锁定同一实例/对象