【问题标题】:Java two synchronized methods in one instanceJava 两个同步方法在一个实例中
【发布时间】:2012-05-21 05:36:34
【问题描述】:

考虑以下代码:

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

【问题讨论】:

    标签: java multithreading synchronization


    【解决方案1】:

    是的,synchronized 关键字是:

    synchronized(this) {
      //...
    }
    

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

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

    【讨论】:

    • 是的,你对扩展线程是正确的,只是修复了代码:)
    【解决方案2】:

    锁总是在整个对象上。如果其中任何一个是 synchronized 成员被访问。

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-03
        • 1970-01-01
        • 1970-01-01
        • 2016-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多