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

MBZ*_*MBZ 12 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();
}
Run Code Online (Sandbox Code Playgroud)

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

编辑: 这不等了吗?

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

Tom*_*icz 13

是的,synchronized关键字是以下的简写:

synchronized(this) {
  //...
}
Run Code Online (Sandbox Code Playgroud)

因此,这两种方法都有效地锁定在同一个互斥对象上.如果你希望它们彼此独立(这个例子中的一个坏主意,因为它们都访问相同的值),请参阅对象锁定私有类成员 - 最佳实践?(Java).

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


San*_*osh 6

锁始终是整个对象上.如果有任何synchronized成员被访问.

在第一个示例中,有两个线程争用同一个 counter对象,一个是显式启动的(increment()在无限循环中调用该方法),另一个线程是主线程(decrement()无限调用).

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