【问题标题】:Synchronizer Confusion同步器混乱
【发布时间】:2019-05-14 00:22:32
【问题描述】:
 class MutableInteger {

    private int value;

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

    public synchronized int getValue() {
        return value;
    }

 public void nonSync(){

 }

}

我正在尝试了解同步关键字的工作原理。

我有一个带有同步方法的类,这意味着在该对象的特定实例上,一次只有一个线程可以调用该方法?这仅与该方法有关吗?因此,如果线程 A 正在调用 incriment,线程 B 是否必须等到线程 A 执行完该方法?但这只是一个方法一个方法的基础?

但是,如果我这样做了

synchronized(this) {
  //code
}

这会锁定对象的整个实例吗?

这有意义吗.. 我从本质上得到了这应该做的事情,只是试图填补空白

【问题讨论】:

  • 它们是一样的。同步存在于实例上,而不是方法上。
  • synchronized 方法在调用方法的实例的监视器上同步,或者在静态方法的类的监视器上同步。每个实例都有一个监视器,每个类都是一个,所以不,它不是一个方法一个方法。它是给定实例的所有实例方法彼此同步以及与该对象上的任何其他同步,并且单独地,同一类的所有静态方法彼此同步并与该类上的任何其他同步。
  • 作为同步的一个例子,这很好,但如果你想使用这样的行为,不要忘记 SDK 提供的 Atomic 类。 AtomicInteger 类与您的代码完全一样,只是以专业的方式;)
  • 另见:locksvolatile fields

标签: java synchronization synchronized


【解决方案1】:

你是对的,同步方法正在锁定实例本身。 所以写如下:

synchronized myMethod() {
    //code
}

本质上和你写的行为是一样的:

myMethod() {
    synchronized(this) {
        //code
    }
}

请注意,this 只是一个Object 并用作任何其他对象的锁 - 锁一次只能由一个线程拥有,其他线程必须等待它进入使用相同对象的 synchronized 块。由于具有synchronized 关键字的方法具有这种行为方式,因此它们共享作为实例本身的锁。

因此,如果您有一个increment()decrement() 方法都标记为synchronized,那么一次只能由一个线程使用这两者中的任何一个。

同时,不带synchronized 关键字的其他方法完全不受影响,并且功能相同,无论它们周围是否有同步方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 2021-04-26
    • 1970-01-01
    相关资源
    最近更新 更多