当前位置: 首页 > 知识库问答 >
问题:

Java同步块-锁定对象

楚翰
2023-03-14

在示例代码中

public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();

public void inc1() {
    synchronized(lock1) {
        c1++;
    }
}

public void inc2() {
    synchronized(lock2) {
        c2++;
    }
}
}

在这个页面上,

lock1和lock2分别控制c1和c2上的更新。

然而,

    synchronized(lock2) 

正在获取对象lock1的锁并在同步块时释放它

    synchronized(lock1) {
        c1++;
    }

被执行。

当这个代码块被执行时,这个对象的成员c1上可能还有一个更新——我看不出这个更新是如何被代码中的lock1上的同步所阻止的。

只有对象lock1可以独占访问——除此之外别无它物(?)

那么,实施情况如何

public void inc1() {
    synchronized(lock1) {
        c1++;
    }
}

在上面的代码中不同于

public void synchronized inc1() {
        c1++;
}

甚至

public void inc1() {
    synchronized(c1) {
        //do something on c1
    }
}

当c1是一个对象而不是一个原语时。

我错过了什么?

注:我看到

在lockObject上同步和将其用作锁之间有什么区别?

Java 同步方法锁定对象,还是方法?

在其他一些讨论中。

共有3个答案

段干宾白
2023-03-14
synchronized(lock2){
  // do sth
}

实际上正在获取对象lock2的锁

在哪里

public void synchronized inc1() {
        c1++;
}

获取此对象上的对象。

一旦程序离开块,synchronized获取的锁将被释放。

姜俊逸
2023-03-14

在不指定锁对象的情况下标记块或方法同步会在拥有该方法的对象上同步;在这种情况下,MsLunch实例。它相当于同步(this)。锁对象习惯用法的目的是打破锁定,以便可以单独操作c1c2同步块只能在对象上同步,不能在原语上同步。

晏昀
2023-03-14

实施1。

您正在锁定lock1对象。需要锁定lock1的任何其他内容都无法执行。将您的两个方法锁定在不同的对象上意味着这两个方法可以同时运行,但没有两个线程可以同时运行相同的方法。

实施2。

使方法< code>synchronized意味着整个方法体隐式位于< code>synchronized(this)块中(或者,如果方法是< code>static,则在< code>Class对象上同步)。如果两个方法都是< code>synchronized,那么一个方法会阻止另一个方法同时运行,这与在不同的对象上锁定两个方法是不同的。

实施 3.

如果<code>c1</code>是一个对象而不是一个原语,那么其语义与实现1非常相似——在显式对象上锁定。

 类似资料:
  • 问题内容: 我正在建模一个游戏,其中多个玩家(线程)同时移动。玩家当前所在位置的信息被存储两次:该玩家具有一个变量“ hostField”,该变量引用板上的一个字段,每个字段都有一个ArrayList,用于存储当前位于该字段的玩家。 我对拥有冗余信息的事实不是很满意,但是我发现如果不遍历大数据集就无法避免这种情况。 但是,当玩家从一个字段移到另一个字段时,我想确保(1)冗余信息保持链接(2)此刻没

  • 假设我有两条线。Thread1正在访问一个同步方法,同时,Thread2正在访问同一对象的另一个同步方法。据我所知,Thread2应该等到Thread1完成它的任务。我的问题是,Thread2是否在对象的等待线程列表中?对我来说似乎是这样,但Thread2不调用wait()方法,那么作为逻辑结果,它不应该在对象的等待线程列表中。如果它不在对象的等待线程列表中,那么Thread2的状态是什么?

  • 问题内容: 输出是 线程1开始 线程1的内部演示 线程2开始 线程2的内部演示 由于,执行尚未结束。 我已经通过类的同一个实例来的两个类的构造函数和。 对in 的调用位于一个块中。 要在通话中是 没有 的块。 所以,当被执行时,由于块,的监视器应锁定,导致拒绝访问,以由所述。 但是,这没有发生。 预期的输出是 (输出在完成之前。) 因此,我的基本问题是: 即使 尚未完成 块, 如何成功执行? 问题

  • 我在学习K K 当一个方法从同步块中执行代码时,代码被称为在同步上下文中执行。当您同步一个方法时,用于调用该方法的对象是必须获取其锁的对象。但是当我们同步代码块时,您必须指定要使用哪个对象的锁作为锁。 在本例中,会在AccountDanger实例或Account对象上获取锁吗?我想应该是这样的。我感觉正确吗?如果它是AccountDanger对象,并且一个线程已获得AccountDanger锁,那

  • 我正在寻找有关同步块的澄清。考虑一下这个类 - A是单例。getValue在整个应用程序中被多个线程大量访问。我添加了一个新方法remove,它从映射中删除一个键。如果如上所述执行删除, 当线程位于remove方法的同步块中时,我假设它将获取map对象上的锁。这是否意味着其他试图通过getValue方法访问映射的线程将被阻止?(我希望他们这样做。) 当remove方法的同步块中没有线程时,访问ge

  • 尝试可视化和理解同步。 对同步块使用静态锁定对象(代码a)和非静态锁定对象(代码B)之间有什么区别 它在实际应用中有什么不同 一方会有哪些陷阱而另一方不会 确定使用哪一个的标准是什么 代码A 代码B 笔记 上面的代码显示了构造函数,但是您可以讨论静态方法和非静态方法中的行为是如何不同的。另外,在同步块修改静态成员变量时使用静态锁是否有利? 我已经看过了这个问题的答案,但是还不清楚不同的使用场景是什