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

java同步和对象锁定

史默
2023-03-14

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

共有2个答案

长孙文栋
2023-03-14

这两种情况是有区别的,正如你所指出的那样。

当一个线程尝试运行一个同步的块,但其他一些线程持有监视器的锁时,传入线程会被阻塞,直到锁被释放并授予它。

对于调用waited()的线程,它必须已经持有监视器的锁(这是一个相关的区别)。此外,调用wait()会使线程等待(释放锁),通常直到它被其他线程通知。

在理想的情况下,通常应该总是这样,但是,正如Java文档中所指定的,可能会出现一种称为虚假唤醒的现象,使得等待的线程无缘无故地被唤醒。这就是为什么等待条件应该包含在while语句中,而不是if语句中。例子:

synchronized (this) {
    while (x < 0) { wait(); }
}

而不是:

synchronized (this) {
    if (x < 0) { wait(); }
}
闻人嘉颖
2023-03-14

当Tread2等待Thread1释放Thread1持有的内在锁时,它会被阻塞,直到内在锁变得可用(如执行线程Thread1释放的u)。因此,在夏季,Thread2正在等待锁被释放,因此它可以获取它。

现在,当线程调用wait()时,它必须已经持有内部锁。调用wait()然后释放锁,并将线程置于等待状态,等待来自notify()或notifyAll()的信号继续执行。

所以,这两种场景是不同的,前者是关于隐式阻止执行,直到资源(锁)可用为止。而后者是关于显式释放已持有的锁,然后等待信号,该是重新获取锁并继续的时候了。

 类似资料:
  • 在示例代码中 在这个页面上, lock1和lock2分别控制c1和c2上的更新。 然而, 正在获取对象lock1的锁并在同步块时释放它 被执行。 当这个代码块被执行时,这个对象的成员c1上可能还有一个更新——我看不出这个更新是如何被代码中的lock1上的同步所阻止的。 只有对象lock1可以独占访问——除此之外别无它物(?) 那么,实施情况如何 在上面的代码中不同于 甚至 当c1是一个对象而不是一

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

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

  • 问题内容: Java教程说:“不可能在同一对象上两次调用同步方法。” 这对于静态方法意味着什么?由于静态方法没有关联的对象,所以synced关键字会锁定在类而不是对象上吗? 问题答案: 由于静态方法没有关联的对象, 所以synced关键字会锁定在类而不是对象上吗? 是。

  • 问题内容: 如果我在同一个类中有2个同步方法,但是每个方法都访问不同的变量,那么2个线程可以同时访问这2个方法吗?锁是否发生在对象上,或者是否与同步方法中的变量一样具体? 例: 2个线程可以同时执行访问类X的相同实例吗? 问题答案: 如果将方法声明为已同步(就像你通过键入进行的操作一样),则会在整个对象上进行同步,因此,从同一对象访问不同变量的两个线程仍然会相互阻塞。 如果你一次只想同步一个变量,